如何searchSQL Server数据库的string?

我知道这是可能的,但不知道如何。

我需要searchMicrosoft SQL数据库中所有提到的特定string。 例如:我想search所有的表,视图,函数,存储过程…string“tblEmployes”。 (不是表格中的数据)

我需要这个的原因之一,我想删除一些额外的数据表创build,但我担心,他们也许在程序或function的某个地方使用。

任何帮助表示赞赏。

这将search特定数据库中每个表的每一列。 在要search的数据库上创build存储过程。

http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/the-ten-most-asked-sql-server-questions–1#2

CREATE PROCEDURE FindMyData_String @DataToFind NVARCHAR(4000), @ExactMatch BIT = 0 AS SET NOCOUNT ON DECLARE @Temp TABLE(RowId INT IDENTITY(1,1), SchemaName sysname, TableName sysname, ColumnName SysName, DataType VARCHAR(100), DataFound BIT) INSERT INTO @Temp(TableName,SchemaName, ColumnName, DataType) SELECT C.Table_Name,C.TABLE_SCHEMA, C.Column_Name, C.Data_Type FROM Information_Schema.Columns AS C INNER Join Information_Schema.Tables AS T ON C.Table_Name = T.Table_Name AND C.TABLE_SCHEMA = T.TABLE_SCHEMA WHERE Table_Type = 'Base Table' And Data_Type In ('ntext','text','nvarchar','nchar','varchar','char') DECLARE @i INT DECLARE @MAX INT DECLARE @TableName sysname DECLARE @ColumnName sysname DECLARE @SchemaName sysname DECLARE @SQL NVARCHAR(4000) DECLARE @PARAMETERS NVARCHAR(4000) DECLARE @DataExists BIT DECLARE @SQLTemplate NVARCHAR(4000) SELECT @SQLTemplate = CASE WHEN @ExactMatch = 1 THEN 'If Exists(Select * From ReplaceTableName Where Convert(nVarChar(4000), [ReplaceColumnName]) = ''' + @DataToFind + ''' ) Set @DataExists = 1 Else Set @DataExists = 0' ELSE 'If Exists(Select * From ReplaceTableName Where Convert(nVarChar(4000), [ReplaceColumnName]) Like ''%' + @DataToFind + '%'' ) Set @DataExists = 1 Else Set @DataExists = 0' END, @PARAMETERS = '@DataExists Bit OUTPUT', @i = 1 SELECT @i = 1, @MAX = MAX(RowId) FROM @Temp WHILE @i <= @MAX BEGIN SELECT @SQL = REPLACE(REPLACE(@SQLTemplate, 'ReplaceTableName', QUOTENAME(SchemaName) + '.' + QUOTENAME(TableName)), 'ReplaceColumnName', ColumnName) FROM @Temp WHERE RowId = @i PRINT @SQL EXEC SP_EXECUTESQL @SQL, @PARAMETERS, @DataExists = @DataExists OUTPUT IF @DataExists =1 UPDATE @Temp SET DataFound = 1 WHERE RowId = @i SET @i = @i + 1 END SELECT SchemaName,TableName, ColumnName FROM @Temp WHERE DataFound = 1 GO 

运行它只是做到这一点:

 exec FindMyData_string 'google', 0 

作品非常好!

如果您需要按名称查找数据库对象(例如表,列,触发器),请查看名为SQL Search的免费 Red-Gate工具,它可以search您的整个数据库中的任何types的string。

在这里输入图像说明

在这里输入图像说明

对于任何DBA或数据库开发人员来说,这是一个很好的必备工具 – 我是否已经提到过它是完全免费的 ,可用于任何types的用途?

您也可以尝试ApexSQLsearch – 这是一个免费的SSMS添加类似于SQLsearch。

如果你真的只想使用SQL你可能想试试这个脚本

 select S.name as [Schema], o.name as [Object], o.type_desc as [Object_Type], C.text as [Object_Definition] from sys.all_objects O inner join sys.schemas S on O.schema_id = S.schema_id inner join sys.syscomments C on O.object_id = C.id where S.schema_id not in (3,4) -- avoid searching in sys and INFORMATION_SCHEMA schemas and C.text like '%ICE_%' order by [Schema] 

在sql server中按名称获取表:

 SELECT * FROM sys.Tables WHERE name LIKE '%Employees%' 

用于通过名称查找存储过程:

 SELECT name FROM sys.objects WHERE name = 'spName' 

获取与表相关的所有存储过程:

 ----Option 1 SELECT DISTINCT so.name FROM syscomments sc INNER JOIN sysobjects so ON sc.id=so.id WHERE sc.TEXT LIKE '%tablename%' ----Option 2 SELECT DISTINCT o.name, o.xtype FROM syscomments c INNER JOIN sysobjects o ON c.id=o.id WHERE c.TEXT LIKE '%tablename%' 

你可以将你的数据库(如果很小)导出到你的硬盘/桌面上,然后通过文本编辑器进行stringsearch。

此代码search程序和function,但不在表中search:)

 SELECT name FROM sys.all_objects WHERE Object_definition(object_id) LIKE '%text%' ORDER BY name 

你可以;

  1. 将数据库脚本编写为单个文件,并使用文本编辑器在文件中searchtblEmployees。 在SQL Serverpipe理工具(SSMS)中,右键单击数据库,然后select“生成脚本”。
  2. 通过右键单击tblEmployees查看哪些其他对象依赖于它,使用SSMS的“查看依赖”
  3. 使用免费的第三方工具(如RedGate SQLSearch)按关键字按名称和内容search所有数据库对象。

这将search每个数据库的string:

 declare @search_term varchar(max) set @search_term = 'something' select @search_term = 'use ? SET QUOTED_IDENTIFIER ON select ''[''+db_name()+''].[''+c.name+''].[''+b.name+'']'' as [object], b.type_desc as [type], d.obj_def.value(''.'',''varchar(max)'') as [definition] from ( select distinct a.id from sys.syscomments a where a.[text] like ''%'+@search_term+'%'' ) a inner join sys.all_objects b on b.[object_id] = a.id inner join sys.schemas c on c.[schema_id] = b.[schema_id] cross apply ( select [text()] = a1.[text] from sys.syscomments a1 where a1.id = a.id order by a1.colid for xml path(''''), type ) d(obj_def) where c.schema_id not in (3,4) -- avoid searching in sys and INFORMATION_SCHEMA schemas and db_id() not in (1,2,3,4) -- avoid sys databases' if object_id('tempdb..#textsearch') is not null drop table #textsearch create table #textsearch ( [object] varchar(300), [type] varchar(300), [definition] varchar(max) ) insert #textsearch exec sp_MSforeachdb @search_term select * from #textsearch order by [object] 

老问题,我知道,但这里是我的版本…我把它命名为“大海捞针”,原因很明显。

它在每行和每列中search特定的值,而不是列名称等。

执行search(当然,replace前两个variables的值):

 DECLARE @SEARCH_DB VARCHAR(100)='REPLACE_WITH_YOUR_DB_NAME' DECLARE @SEARCH_VALUE_LIKE NVARCHAR(100)=N'%REPLACE_WITH_SEARCH_STRING%' SET NOCOUNT ON; DECLARE col_cur CURSOR FOR SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM information_schema.columns WHERE TABLE_CATALOG=@SEARCH_DB AND DATA_TYPE NOT IN ('timestamp', 'datetime'); DECLARE @TOTAL int = (SELECT COUNT(*) FROM information_schema.columns WHERE TABLE_CATALOG=@SEARCH_DB AND DATA_TYPE NOT IN ('timestamp', 'datetime')); DECLARE @TABLE_CATALOG nvarchar(500), @TABLE_SCHEMA nvarchar(500), @TABLE_NAME nvarchar(500), @COLUMN_NAME nvarchar(500), @DATA_TYPE nvarchar(500); DECLARE @SQL nvarchar(4000)=''; PRINT '-------- BEGIN SEARCH --------'; OPEN col_cur; FETCH NEXT FROM col_cur INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME, @COLUMN_NAME, @DATA_TYPE; BEGIN TRY DROP TABLE ##RESULTS; END TRY BEGIN CATCH END CATCH CREATE TABLE ##RESULTS( TABLE_CATALOG nvarchar(500), TABLE_SCHEMA nvarchar(500), TABLE_NAME nvarchar(500), COLUMN_NAME nvarchar(500), DATA_TYPE nvarchar(500), RECORDS int) DECLARE @SHOULD_CAST bit=0 DECLARE @i int =0 DECLARE @progress_sum bigint=0 WHILE @@FETCH_STATUS = 0 BEGIN -- PRINT '' + CAST(@i as varchar(100)) +' of ' + CAST(@TOTAL as varchar(100)) + ' ' + @TABLE_CATALOG+'.'+@TABLE_SCHEMA+'.'+@TABLE_NAME+': '+@COLUMN_NAME+' ('+@DATA_TYPE+')'; SET @SHOULD_CAST = (SELECT CASE @DATA_TYPE WHEN 'varchar' THEN 0 WHEN 'nvarchar' THEN 0 WHEN 'char' THEN 0 ELSE 1 END) SET @SQL='SELECT '''+@TABLE_CATALOG+''' catalog_name, '''+@TABLE_SCHEMA+''' schema_name, '''+@TABLE_NAME+''' table_name, '''+@COLUMN_NAME+''' column_name, '''+@DATA_TYPE+''' data_type, ' + +' COUNT(['+@COLUMN_NAME+']) records '+ +' FROM '+@TABLE_CATALOG+'.'+@TABLE_SCHEMA+'.'+@TABLE_NAME + +' WHERE ' + CASE WHEN @SHOULD_CAST=1 THEN 'CAST(['+@COLUMN_NAME + '] as NVARCHAR(max)) ' ELSE ' ['+@COLUMN_NAME + '] ' END +' LIKE '''+ @SEARCH_VALUE_LIKE + ''' ' -- PRINT @SQL; IF @i % 100 = 0 BEGIN SET @progress_sum = (SELECT SUM(RECORDS) FROM ##RESULTS) PRINT CAST (@i as varchar(100)) +' of ' + CAST(@TOTAL as varchar(100)) +': '+ CAST (@progress_sum as varchar(100)) END INSERT INTO ##RESULTS (TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE, RECORDS) EXEC(@SQL) FETCH NEXT FROM col_cur INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME, @COLUMN_NAME, @DATA_TYPE; SET @i=@i+1 -- IF @i > 1000 -- BREAK END CLOSE col_cur; DEALLOCATE col_cur; SELECT * FROM ##RESULTS WHERE RECORDS>0; 

然后查看结果,即使在执行时,从另一个窗口执行:

 DECLARE @SEARCH_VALUE_LIKE NVARCHAR(100)=N'%@FLEX@%' SELECT * FROM ##RESULTS WHERE RECORDS>0; SET NOCOUNT ON; DECLARE col_cur CURSOR FOR SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM ##RESULTS WHERE RECORDS>0; DECLARE @TABLE_CATALOG nvarchar(500), @TABLE_SCHEMA nvarchar(500), @TABLE_NAME nvarchar(500), @COLUMN_NAME nvarchar(500), @DATA_TYPE nvarchar(500); DECLARE @SQL nvarchar(4000)=''; OPEN col_cur; FETCH NEXT FROM col_cur INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME, @COLUMN_NAME, @DATA_TYPE; DECLARE @i int =0 DECLARE @SHOULD_CAST bit=0 WHILE @@FETCH_STATUS = 0 BEGIN SET @SHOULD_CAST = (SELECT CASE @DATA_TYPE WHEN 'varchar' THEN 0 WHEN 'nvarchar' THEN 0 WHEN 'char' THEN 0 ELSE 1 END) SET @SQL='SELECT '''+@TABLE_CATALOG+''' catalog_name, '''+@TABLE_SCHEMA+''' schema_name, '''+@TABLE_NAME+''' table_name, '''+@COLUMN_NAME+''' column_name, '''+@DATA_TYPE+''' data_type, ' + +' ['+@COLUMN_NAME+']'+ +', * ' +' FROM '+@TABLE_CATALOG+'.'+@TABLE_SCHEMA+'.'+@TABLE_NAME + +' WHERE ' + CASE WHEN @SHOULD_CAST=1 THEN 'CAST(['+@COLUMN_NAME + '] as NVARCHAR(max)) ' ELSE ' ['+@COLUMN_NAME + '] ' END +' LIKE '''+ @SEARCH_VALUE_LIKE + ''' ' PRINT @SQL; EXEC(@SQL) FETCH NEXT FROM col_cur INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME, @COLUMN_NAME, @DATA_TYPE; SET @i=@i+1 -- IF @i > 10 -- BREAK END CLOSE col_cur; DEALLOCATE col_cur; 

几乎没有提到它:

  • 它使用游标而不是阻塞while循环
  • 它可以打印进度(如果需要取消注释)
  • 它可以在几次尝试后退出(在最后取消IF的注释)
  • 它显示所有logging
  • 您可以根据需要对其进行微调

免责声明:

  • 不要在生产环境中运行它!
  • 这是慢的。 如果数据库被其他服务/用户访问,请在所有select中的每个表名之后添加“WITH(NOLOCK)”,尤其是dynamicselect的表。
  • 它不validation/防范各种SQL注入选项。
  • 如果您的数据库很大,请准备好进行一些睡眠,确保查询几分钟后不会中断。
  • 它将一些值转换为string,包括ints / bigints / smallints / tinyints。 如果你不需要这些,把它们放在同一个排除列表中,并在脚本的顶部加上时间戳。

希望这可以帮助。

被授予访问数据库,但不是我的查询被存储在表中。

受@marc_s答案的启发,我看了一下HeidiSQL ,它是一个可以处理MySQL,MSSQL和PostgreSQL的Windows程序。

发现它也可以在数据库中search一个string。

点击搜索,然后在服务器上查找文本

搜索工具打开。确保数据库已被选中

它会search每个表,并给你多less次find每个表的string!

假设你不会在整个数据库中进行公开search,而只是想自己找一个关键字,这是最简单,更干净,更快速的解决scheme。

  1. 将数据库转储到文件。

     $ mysqldump -u root -p your_database > your_database.sql 
  2. 对该文件做一个grep

     $ grep 'keyword' your_database.sql 

你完成了。