给定#,我如何发现它可以在哪个表和列中找到?
我不在乎它是否快,它只需要工作.
这可能对你有帮助. - 来自Narayana Vyas.它搜索给定数据库中所有表的所有列.我之前使用它并且它有效.
这是上面链接中的存储过程 - 我做的唯一更改是将临时表替换为表变量,因此您不必每次都记得丢弃它.
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 DECLARE @Results TABLE(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
如果您只需要运行一次这样的搜索,那么您可以使用此处已显示的任何脚本.但除此之外,我建议使用ApexSQL搜索.这是一个免费的SSMS插件,它真的为我节省了很多时间.
在运行上述任何脚本之前,您应该根据要查看的数据类型对其进行自定义.如果您知道正在搜索datetime列,则无需搜索nvarchar列.这将加快上述所有查询.
基于bnkdev的回答,我修改了Narayana的代码来搜索所有列甚至数字列.
它会运行得更慢,但这个版本实际上找到的所有匹配项不仅仅是在文本列中找到的匹配项.
我不能完全感谢这个家伙.救了我几天手工搜索!
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 QUOTENAME(COLUMN_NAME) > @ColumnName ) IF @ColumnName IS NOT NULL BEGIN INSERT INTO #Results EXEC ( 'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(CONVERT(varchar(max), ' + @ColumnName + '), 3630) FROM ' + @TableName + ' (NOLOCK) ' + ' WHERE CONVERT(varchar(max), ' + @ColumnName + ') LIKE ' + @SearchStr2 ) END END END SELECT ColumnName, ColumnValue FROM #Results END
这是我对这个问题的独立看法,我将其用于自己的工作.它适用于SQL2000及更高版本,允许使用通配符,列过滤,并将搜索大多数普通数据类型.
伪代码描述可以是 select * from * where any like 'foo'
-------------------------------------------------------------------------------- -- Search all columns in all tables in a database for a string. -- Does not search: image, sql_variant or user-defined types. -- Exact search always for money and smallmoney; no wildcards for matching these. -------------------------------------------------------------------------------- declare @SearchTerm nvarchar(4000) -- Can be max for SQL2005+ declare @ColumnName sysname -------------------------------------------------------------------------------- -- SET THESE! -------------------------------------------------------------------------------- set @SearchTerm = N'foo' -- Term to be searched for, wildcards okay set @ColumnName = N'' -- Use to restrict the search to certain columns, wildcards okay, null or empty string for all cols -------------------------------------------------------------------------------- -- END SET -------------------------------------------------------------------------------- set nocount on declare @TabCols table ( id int not null primary key identity , table_schema sysname not null , table_name sysname not null , column_name sysname not null , data_type sysname not null ) insert into @TabCols (table_schema, table_name, column_name, data_type) select t.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE from INFORMATION_SCHEMA.TABLES t join INFORMATION_SCHEMA.COLUMNS c on t.TABLE_SCHEMA = c.TABLE_SCHEMA and t.TABLE_NAME = c.TABLE_NAME where 1 = 1 and t.TABLE_TYPE = 'base table' and c.DATA_TYPE not in ('image', 'sql_variant') and c.COLUMN_NAME like case when len(@ColumnName) > 0 then @ColumnName else '%' end order by c.TABLE_NAME, c.ORDINAL_POSITION declare @table_schema sysname , @table_name sysname , @column_name sysname , @data_type sysname , @exists nvarchar(4000) -- Can be max for SQL2005+ , @sql nvarchar(4000) -- Can be max for SQL2005+ , @where nvarchar(4000) -- Can be max for SQL2005+ , @run nvarchar(4000) -- Can be max for SQL2005+ while exists (select null from @TabCols) begin select top 1 @table_schema = table_schema , @table_name = table_name , @exists = 'select null from [' + table_schema + '].[' + table_name + '] where 1 = 0' , @sql = 'select ''' + '[' + table_schema + '].[' + table_name + ']' + ''' as TABLE_NAME, * from [' + table_schema + '].[' + table_name + '] where 1 = 0' , @where = '' from @TabCols order by id while exists (select null from @TabCols where table_schema = @table_schema and table_name = @table_name) begin select top 1 @column_name = column_name , @data_type = data_type from @TabCols where table_schema = @table_schema and table_name = @table_name order by id -- Special case for money if @data_type in ('money', 'smallmoney') begin if isnumeric(@SearchTerm) = 1 begin set @where = @where + ' or [' + @column_name + '] = cast(''' + @SearchTerm + ''' as ' + @data_type + ')' -- could also cast the column as varchar for wildcards end end -- Special case for xml else if @data_type = 'xml' begin set @where = @where + ' or cast([' + @column_name + '] as nvarchar(max)) like ''' + @SearchTerm + '''' end -- Special case for date else if @data_type in ('date', 'datetime', 'datetime2', 'datetimeoffset', 'smalldatetime', 'time') begin set @where = @where + ' or convert(nvarchar(50), [' + @column_name + '], 121) like ''' + @SearchTerm + '''' end -- Search all other types else begin set @where = @where + ' or [' + @column_name + '] like ''' + @SearchTerm + '''' end delete from @TabCols where table_schema = @table_schema and table_name = @table_name and column_name = @column_name end set @run = 'if exists(' + @exists + @where + ') begin ' + @sql + @where + ' print ''' + @table_name + ''' end' print @run exec sp_executesql @run end set nocount off
我不把它放在proc表单中,因为我不想在数百个DB中维护它,而且它确实用于临时工作.请随时评论错误修复.
我优化了Allain Lalonde的答案(/sf/ask/17360801/).仍支持数值.应该大约快4-5倍(1:03 vs 4:30),在具有7GB数据库的桌面上进行测试.http://developer.azurewebsites.net/2015/01/mssql-searchalltables/
IF OBJECT_ID ('dbo.SearchAllTables', 'P') IS NOT NULL DROP PROCEDURE dbo.SearchAllTables; GO 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 -- Customized and modified: 2014-01-21 -- Tested on: SQL Server 2008 R2 DECLARE @Results TABLE(ColumnName nvarchar(370), ColumnValue nvarchar(3630)) SET NOCOUNT ON DECLARE @TableName nvarchar(256) DECLARE @ColumnName nvarchar(128) DECLARE @DataType nvarchar(128) DECLARE @SearchStr2 nvarchar(110) DECLARE @SearchDecimal decimal(38,19) DECLARE @Query nvarchar(4000) SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%', '''') SET @SearchDecimal = CASE WHEN ISNUMERIC(@SearchStr) = 1 THEN CONVERT(decimal(38,19), @SearchStr) ELSE NULL END PRINT '@SearchStr2: ' + @SearchStr2 PRINT '@SearchDecimal: ' + CAST(@SearchDecimal AS nvarchar) SET @TableName = '' 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)) DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2) AND TABLE_NAME = PARSENAME(@TableName, 1) AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'bigint', 'tinyint', 'numeric', 'decimal') AND QUOTENAME(COLUMN_NAME) > @ColumnName ) SET @DataType = ( SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2) AND TABLE_NAME = PARSENAME(@TableName, 1) AND QUOTENAME(COLUMN_NAME) = @ColumnName ) PRINT @TableName + '.' + @ColumnName + ' (' + @DataType + ')' IF @ColumnName IS NOT NULL BEGIN IF @DataType IN ('int', 'bigint', 'tinyint', 'numeric', 'decimal') BEGIN IF @SearchDecimal IS NOT NULL BEGIN SET @Query = 'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(CAST(' + @ColumnName + ' AS nvarchar(110)), 3630) ' + 'FROM ' + @TableName + ' (NOLOCK) ' + ' WHERE ' + @ColumnName + ' = ' + CAST(@SearchDecimal AS nvarchar) PRINT ' ' + @Query INSERT INTO @Results EXEC (@Query) END END ELSE BEGIN SET @Query = 'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) ' + 'FROM ' + @TableName + ' (NOLOCK) ' + ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 PRINT ' ' + @Query INSERT INTO @Results EXEC (@Query) END END END END SELECT ColumnName, ColumnValue FROM @Results END