我有一个特定的字符串,例如“123abcd”,但我不知道表的名称,甚至不知道SQL Server数据库中表的列名。我想用select找到它并显示相关字符串的所有列,所以我想知道类似的东西:
select * from Database.dbo.* where * like '%123abcd%'
由于显而易见的原因它不起作用,但有一种简单的方法可以创建一个select语句来做这样的事情吗?
答案 0 :(得分:28)
这将有效:
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
这样的值没有按预期转换的问题,因此在它们应该是(假阴性)时不匹配。
WHERE (0 = 1)
可以让您更轻松地构建OR
子句。如果没有匹配,则不会返回任何行。
答案 1 :(得分:12)
以下是一些可用于此的免费工具。两者都作为SSMS插件工作。
ApexSQL Search - 100%免费 - 搜索表格中的架构和数据。有几个更有用的选项,如依赖关系跟踪......
SSMS Tools pack - 除了SQL 2012以外的所有版本都免费 - 看起来不像以前的版本那么先进,但还有很多其他很酷的功能。
答案 2 :(得分:4)
我认为你必须选择:
使用sys.tables
和sys.columns
构建动态SQL以执行搜索(example here)。
使用具有此功能的任何程序。一个例子是SQL Workbench(免费)。
答案 3 :(得分:4)
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
答案 4 :(得分:3)
在oracle中,您可以使用以下sql命令生成所需的sql命令:
select
"select * "
" from "||table_name||
" where "||column_name||" like '%123abcd%' ;" as sql_command
from user_tab_columns
where data_type='VARCHAR2';
答案 5 :(得分:2)
我通常使用information_Schema.columns
和information_schema.tables
,虽然像@yuck说的那样,sys.tables
和sys.columns
的输入时间较短。
在循环中,连接这些
@sql = @sql + 'select' + column_name +
' from ' + table_name +
' where ' + column_name ' like ''%''+value+''%' UNION
然后执行生成的sql。
答案 6 :(得分:2)
SQL Locator(免费)对我有用。它有很多选项,而且使用起来相当容易。
答案 7 :(得分:2)
Common Resource Grep(crgrep)将按名称或内容搜索表/列中的字符串匹配,并支持许多DB,包括SQLServer,Oracle等。完整的野性梳理和其他有用的选择。
这是开源(我是作者)。
答案 8 :(得分:2)
对于迟到的回答感到抱歉,但我也遇到了这个问题,并最终使用另一种可能对所有数据库更通用的方法来解决它。
答案 9 :(得分:0)
这是一个简单方便的基于光标的解决方案
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