我正在做的目的是启用一个脚本,该脚本在运行时将在数据库中显示的任何位置显示指定术语的每个实例。
我有一个脚本,用于显示指定表上某个术语的实例。我通过一个游标扩展了该脚本,该游标将首先为每个不同的表名称索引数据库,然后运行查询,并在每个表的行中显示找到术语的所有数据。例如,如果您要在全球范围内搜索术语铝或铅的实例,则只要在任何地方使用了确切的术语,就可以显示@stringtofind ='aluminum'的值,否则将显示'%lead%'该单词作为字段的实例,或者包含该单词的术语。
这确实有效,但是,更好的版本将是在一个查询中获得结果,而不是运行多个查询,因为这可能会令人望而却步,并且还会使数据难以解析。
理想情况下,我希望改为使用具有三列的单个查询,例如:
TableName,ColumnName,FieldContainingSpecifiedTerm
我想如果可以将两列的内容合并到一个列中,则可以以一种更简单的方式完成此操作。 Concat和Union分别被严格禁止,因为这会产生大量concat,结果可能包含所讨论的数据,但是合并在一起后很快就失去了价值,并且要求使用相同数量的字段工会。
我相信,如果一次将一列的字段更改为VARCHAR 100或类似的包含全部或接近全部的数据类型(例如,全部转换),则可以使用强制转换或转换将一列中的数据添加到一百个或更多字符的文本字段,将每一行部署到一个虚拟列中,然后移至下一列并重复。可以对表中的每一列重复此操作,然后可以将诸如游标之类的内容移至列表中的下一个表并重复,最终结果实际上是数据库的每一行都位于一列中。
如果可能的话,可以使用一个简单的where子句来查找必要的信息,同样,如果该行还具有表示结果的身份和来源的其他列,则可以在任何地方跟踪特定术语的条目他们已经出现了。
这是我目前拥有的脚本:
--This will list each instance of a field with the data "sample" in it
DECLARE @stringtofind VARCHAR(100)= 'sample', @schema SYSNAME= 'dbo', @table SYSNAME;
DECLARE @sqlCommand VARCHAR(8000);
DECLARE @where VARCHAR(8000);
DECLARE @columnName SYSNAME;
DECLARE @cursor VARCHAR(8000);
DECLARE TableList CURSOR
FOR SELECT DISTINCT
o.name
FROM sys.columns c
JOIN sys.types t ON c.user_type_id = t.user_type_id
JOIN sys.objects o ON c.object_id = o.object_id
JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE c.name LIKE '%'
AND o.type_desc = 'user_table'
ORDER BY name;
OPEN TableList;
FETCH NEXT FROM TableList INTO @table;
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
SET @sqlCommand = 'SELECT * FROM ['+@schema+'].['+@table+'] WHERE';
SET @where = '';
SET @cursor = 'DECLARE col_cursor CURSOR FOR SELECT COLUMN_NAME
FROM '+DB_NAME()+'.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '''+@schema+'''
AND TABLE_NAME = '''+@table+'''
AND DATA_TYPE IN (''char'',''nchar'',''ntext'',''nvarchar'',''text'',''varchar'')';
EXEC (@cursor);
OPEN col_cursor;
FETCH NEXT FROM col_cursor INTO @columnName;
WHILE @@FETCH_STATUS = 0
BEGIN
IF @where <> ''
SET @where = @where+' OR';
SET @where = @where+' ['+@columnName+'] LIKE '''+@stringToFind+'''';
FETCH NEXT FROM col_cursor INTO @columnName;
END;
CLOSE col_cursor;
DEALLOCATE col_cursor;
SET @sqlCommand = @sqlCommand + @where;
PRINT @sqlCommand;
EXEC (@sqlCommand);
END TRY
BEGIN CATCH
PRINT 'There was an error. Check to make sure object exists.';
PRINT ERROR_MESSAGE();
IF CURSOR_STATUS('variable', 'col_cursor') <> -3
BEGIN
CLOSE col_cursor;
DEALLOCATE col_cursor;
END;
END CATCH;
FETCH NEXT FROM TableList INTO @table;
END;
CLOSE TableList;
DEALLOCATE TableList;
GO