我有一个庞大的架构,其中包含数百个表和数千个列。我知道特定的IP地址存储在此数据库中的多个位置,但是我不确定它存储在哪个表或列中。基本上,我试图在各处找到该IP地址IP地址存储在数据库中,因此我可以在所有这些位置将其更新为新值。
这是我第一次尝试使用T-SQL语句为数据库中每个包含子字符串10.15.13的文本列打印表和列的名称以及值。
现在,这有点有效。问题是,当我在Management Studio中执行它时,对sp_executesql的调用实际上将返回每个不返回任何内容的查询的所有空结果(即,该列没有该子字符串的任何记录),并且它填充了结果窗口到最大程度,然后我实际上看不到是否打印了任何东西。
有没有更好的方法来编写此查询?还是可以以其他方式运行它,以便仅向我显示该子字符串所在的表和列?
DECLARE @SchemaName VARCHAR(50), @TableName VARCHAR(50), @ColumnName VARCHAR(50); BEGIN DECLARE textColumns CURSOR FOR SELECT s.Name, tab.Name, c.Name FROM Sys.Columns c, Sys.Types t, Sys.Tables tab, Sys.Schemas s WHERE s.schema_id = tab.schema_id AND tab.object_id = c.object_id AND c.user_type_id = t.user_type_id AND t.Name in ('TEXT','NTEXT','VARCHAR','CHAR','NVARCHAR','NCHAR'); OPEN textColumns FETCH NEXT FROM textColumns INTO @SchemaName, @TableName, @ColumnName WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @sql NVARCHAR(MAX), @ParamDef NVARCHAR(MAX), @result NVARCHAR(MAX); SET @sql = N'SELECT ' + @ColumnName + ' FROM ' + @SchemaName + '.' + @TableName + ' WHERE ' + @ColumnName + ' LIKE ''%10.15.13%'''; SET @ParamDef = N'@resultOut NVARCHAR(MAX) OUTPUT'; EXEC sp_executesql @sql, @ParamDef, @resultOut = @result OUTPUT; PRINT 'Column = ' + @TableName + '.' + @ColumnName + ', Value = ' + @result; FETCH NEXT FROM textColumns INTO @SchemaName, @TableName, @ColumnName END CLOSE textColumns; DEALLOCATE textColumns; END
我希望看到类似这样的结果,其中显示在其中找到子字符串的表/列以及该列中的完整值…
Column = SomeTable.SomeTextColumn, Value = 'https://10.15.13.210/foo' Column = SomeTable.SomeOtherColumn, Value = '10.15.13.210'
等等。
你近了 将此示例与您的示例进行比较:在SQL Server表的所有列中搜索和查找字符串值
上面的链接用于搜索单个表,但是这里是另一个包含所有表的链接:如何在数据库中所有表的所有列中搜索关键字?
编辑:以防万一链接变坏,这是该链接的解决方案…
CREATE PROC SearchAllTables ( @SearchStr nvarchar(100) ) AS BEGIN -- Copyright 漏 2002 Narayana Vyas Kondreddi. All rights reserved. -- Purpose: To search all columns of all tables for a given search string -- Written by: Narayana Vyas Kondreddi -- Site: http://vyaskn.tripod.com -- Tested on: SQL Server 7.0 and SQL Server 2000 -- Date modified: 28th July 2002 22:50 GMT CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630)) SET NOCOUNT ON DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110) SET @TableName = '' SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''') WHILE @TableName IS NOT NULL BEGIN SET @ColumnName = '' SET @TableName = ( SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName AND OBJECTPROPERTY( OBJECT_ID( QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) ), 'IsMSShipped' ) = 0 ) WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL) BEGIN SET @ColumnName = ( SELECT MIN(QUOTENAME(COLUMN_NAME)) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2) AND TABLE_NAME = PARSENAME(@TableName, 1) AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar') AND QUOTENAME(COLUMN_NAME) > @ColumnName ) IF @ColumnName IS NOT NULL BEGIN INSERT INTO #Results EXEC ( 'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) FROM ' + @TableName + ' (NOLOCK) ' + ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 ) END END END SELECT ColumnName, ColumnValue FROM #Results END EXEC SearchAllTables '<yourSubstringHere>'
注意:正如注释在代码段中所建议的那样,已使用较旧版本的SQL Server对它进行了测试。这可能不适用于SQL Server 2012。