如何在整个数据库中查找string?
我有一个特定的string,例如“123abcd”,但我不知道表的名称,甚至不知道我的SQL Server数据库表中的列的名称。 我想find一个select并显示相关string的所有列,所以我想知道这样的:
select * from Database.dbo.* where * like '%123abcd%'
由于显而易见的原因,它不工作,但有一个简单的方法来创build一个select语句来做这样的事情?
这将工作:
DECLARE @MyValue NVarChar(4000) = 'something'; SELECT S.name SchemaName, T.name TableName INTO #T FROM sys.schemas S INNER JOIN sys.tables T ON S.schema_id = T.schema_id; WHILE (EXISTS (SELECT * FROM #T)) BEGIN DECLARE @SQL NVarChar(4000) = 'SELECT * FROM $$TableName WHERE (0 = 1) '; DECLARE @TableName NVarChar(1000) = ( SELECT TOP 1 SchemaName + '.' + TableName FROM #T ); SELECT @SQL = REPLACE(@SQL, '$$TableName', @TableName); DECLARE @Cols NVarChar(4000) = ''; SELECT @Cols = COALESCE(@Cols + 'OR CONVERT(NVarChar(4000), ', '') + C.name + ') = CONVERT(NVarChar(4000), ''$$MyValue'') ' FROM sys.columns C WHERE C.object_id = OBJECT_ID(@TableName); SELECT @Cols = REPLACE(@Cols, '$$MyValue', @MyValue); SELECT @SQL = @SQL + @Cols; EXECUTE(@SQL); DELETE FROM #T WHERE SchemaName + '.' + TableName = @TableName; END; DROP TABLE #T;
不过,一些注意事项。 首先, 这是非常慢和不优化 。 所有的值都被简单地转换为nvarchar
以便可以无差错地进行比较。 你可能会遇到类似datetime
问题,而不是像预期的那样进行转换,因此当它们应该是不匹配的时候(false negatives)。
WHERE (0 = 1)
是为了更容易地构buildOR
子句。 如果没有匹配,你将不会得到任何行。
这里有更多的免费工具可以用于这个。 两者都作为SSMS插件。
ApexSQLsearch – 100%免费 – 在表格中search模式和数据。 有几个更有用的选项,如依赖关系跟踪…
除了SQL 2012以外,所有版本的SSMS工具包都是免费的 – 看起来不像以前那么先进,但是有很多其他很酷的function。
我认为你必须select:
-
使用
sys.tables
和sys.columns
构builddynamicSQL来执行search( 此处为示例 )。 -
使用任何具有此function的程序。 SQL Workbench (免费)就是一个例子。
create procedure usp_find_string(@string as varchar(1000)) as begin declare @mincounter as int declare @maxcounter as int declare @stmtquery as varchar(1000) set @stmtquery='' create table #tmp(tablename varchar(128),columnname varchar(128),rowid int identity) create table #tablelist(tablename varchar(128),columnname varchar(128)) declare @tmp table(name varchar(128)) declare @tablename as varchar(128) declare @columnname as varchar(128) insert into #tmp(tablename,columnname) select a.name,b.name as columnname from sysobjects a inner join syscolumns b on a.name=object_name(b.id) where a.type='u' and b.xtype in(select xtype from systypes where name='text' or name='ntext' or name='varchar' or name='nvarchar' or name='char' or name='nchar') order by a.name select @maxcounter=max(rowid),@mincounter=min(rowid) from #tmp while(@mincounter <= @maxcounter ) begin select @tablename=tablename, @columnname=columnname from #tmp where rowid=@mincounter set @stmtquery ='select top 1 ' + '[' +@columnname+']' + ' from ' + '['+@tablename+']' + ' where ' + '['+@columnname+']' + ' like ' + '''%' + @string + '%''' insert into @tmp(name) exec(@stmtquery) if @@rowcount >0 insert into #tablelist values(@tablename,@columnname) set @mincounter=@mincounter +1 end select * from #tablelist end
在oracle中你可以使用下面的sql命令来生成你需要的sql命令:
select "select * " " from "||table_name|| " where "||column_name||" like '%123abcd%' ;" as sql_command from user_tab_columns where data_type='VARCHAR2';
SQL定位器 (免费)为我工作的很好。 它有很多选项,使用起来相当简单。
我通常使用information_Schema.columns
和information_schema.tables
,虽然像@yuck所说, sys.tables
和sys.columns
是短的types。
在一个循环中,连接这些
@sql = @sql + 'select' + column_name + ' from ' + table_name + ' where ' + column_name ' like ''%''+value+''%' UNION
然后执行生成的sql。
公共资源Grep(crgrep)将按名称或内容search表/列中的string匹配,并支持许多数据库,包括SQLServer,Oracle等。 充分的野生梳理和其他有用的select。
这是开源(我是作者)。
对不起,对于迟到的答案,但我也有这个问题,并最终解决了使用另一种方法,可能是更通用的所有数据库。
- 创build一个数据库转储。
- 从那里你应该能够在文本编辑器中打开文件并search所需的string。
这是一个基于游标的解决scheme
DECLARE @search_string VARCHAR(100), @table_name SYSNAME, @table_id INT, @column_name SYSNAME, @sql_string VARCHAR(2000) SET @search_string = 'StringtoSearch' DECLARE tables_cur CURSOR FOR SELECT name, object_id FROM sys.objects WHERE type = 'U' OPEN tables_cur FETCH NEXT FROM tables_cur INTO @table_name, @table_id WHILE (@@FETCH_STATUS = 0) BEGIN DECLARE columns_cur CURSOR FOR SELECT name FROM sys.columns WHERE object_id = @table_id AND system_type_id IN (167, 175, 231, 239) OPEN columns_cur FETCH NEXT FROM columns_cur INTO @column_name WHILE (@@FETCH_STATUS = 0) BEGIN SET @sql_string = 'IF EXISTS (SELECT * FROM ' + @table_name + ' WHERE [' + @column_name + '] LIKE ''%' + @search_string + '%'') PRINT ''' + @table_name + ', ' + @column_name + '''' EXECUTE(@sql_string) FETCH NEXT FROM columns_cur INTO @column_name END CLOSE columns_cur DEALLOCATE columns_cur FETCH NEXT FROM tables_cur INTO @table_name, @table_id END CLOSE tables_cur DEALLOCATE tables_cur