Search text in stored procedure in SQL Server
我要从所有数据库存储过程中搜索文本。我使用下面的SQL:
1 2 3 4 5 6 7 8 | SELECT DISTINCT o.name AS Object_Name, o.type_desc FROM sys.sql_modules m INNER JOIN sys.objects o ON m.object_id = o.object_id WHERE m.definition LIKE '%[ABD]%'; |
我想在包括方括号在内的所有存储过程中搜索
退出方括号:
1 2 | ... WHERE m.definition LIKE '%\[ABD\]%' ESCAPE '\' |
号
然后方括号将被视为字符串而不是通配符。
尝试此请求:
查询
1 2 3 | SELECT name FROM sys.procedures WHERE Object_definition(object_id) LIKE '%strHell%' |
您是否尝试使用第三方工具进行搜索?有几个是免费的,这在过去为我节省了很多时间。
下面是我成功使用的两个SSMS加载项。
apexsql搜索–在数据库中搜索模式和数据,并具有附加功能,如依赖项跟踪等…
SSMS工具包–具有与前一个功能相同的搜索功能和其他几个很酷的功能。对于SQL Server 2012来说不是免费的,但仍然非常实惠。
我知道这个答案并不是100%与问题相关(更具体一些),但希望其他人会发现这一点有用。
我通常运行以下程序来实现这一点:
1 2 3 4 | SELECT DISTINCT object_name(id) FROM syscomments WHERE text LIKE '%[ABD]%' ORDER BY object_name(id) |
Redgate的SQL搜索是一个很好的工具,它是SSMS的免费插件。
使用SQL Server的良好实践。
进行以下存储过程,并为底部图像等设置短键,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | CREATE PROCEDURE [dbo].[Searchinall] (@strFind AS VARCHAR(MAX)) AS BEGIN SET NOCOUNT ON; --TO FIND STRING IN ALL PROCEDURES BEGIN SELECT OBJECT_NAME(OBJECT_ID) SP_Name ,OBJECT_DEFINITION(OBJECT_ID) SP_Definition FROM sys.procedures WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%'+@strFind+'%' END --TO FIND STRING IN ALL VIEWS BEGIN SELECT OBJECT_NAME(OBJECT_ID) View_Name ,OBJECT_DEFINITION(OBJECT_ID) View_Definition FROM sys.views WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%'+@strFind+'%' END --TO FIND STRING IN ALL FUNCTION BEGIN SELECT ROUTINE_NAME Function_Name ,ROUTINE_DEFINITION Function_definition FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_DEFINITION LIKE '%'+@strFind+'%' AND ROUTINE_TYPE = 'FUNCTION' ORDER BY ROUTINE_NAME END --TO FIND STRING IN ALL TABLES OF DATABASE. BEGIN SELECT t.name AS TABLE_NAME ,c.name AS COLUMN_NAME FROM sys.tables AS t INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID WHERE c.name LIKE '%'+@strFind+'%' ORDER BY TABLE_NAME END END |
号
现在-设置短键如下,
。
所以下次当你想在四个对象中找到一个特定的文本时,比如
例如:我要搜索"paymenttable",然后在查询编辑器中编写"paymenttable",然后按短键
请把它作为一个"肮脏"的选择,但这节省了我很多次,尤其是当我不熟悉数据库项目时。有时,您试图在所有SP中搜索一个字符串,但却忘记了某些相关逻辑可能隐藏在函数和触发器之间,或者只是用不同于您想象的语言来表达。
从您的MSSMS中,您可以右键单击数据库并选择
氧化镁
确保也选择触发器!
氧化镁
然后使用Sublime或记事本搜索需要查找的字符串。我知道这可能是非常低效和偏执的方法,但它是有效的:)
您也可以使用这个:
1 2 3 | SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_DEFINITION LIKE '%Search_String%' |
。
1 2 3 | SELECT top 10 * FROM sys.procedures WHERE object_definition(object_id) LIKE '%\[ABD\]%' |
。
这可能对你有帮助!
1 2 3 4 5 6 7 | SELECT DISTINCT A.NAME AS OBJECT_NAME, A.TYPE_DESC FROM SYS.SQL_MODULES M INNER JOIN SYS.OBJECTS A ON M.OBJECT_ID = A.OBJECT_ID WHERE M.DEFINITION LIKE '%['+@SEARCH_TEXT+']%' ORDER BY TYPE_DESC |
号
1 2 3 4 5 | SELECT DISTINCT o.name AS Object_Name, o.type_desc FROM sys.sql_modules m INNER JOIN sys.objects o ON m.object_id = o.object_id WHERE m.definition LIKE '%[String]%'; |
号
您还可以使用:
1 2 3 4 5 | SELECT OBJECT_NAME(id) FROM syscomments WHERE [text] LIKE '%flags.%' AND OBJECTPROPERTY(id, 'IsProcedure') = 1 GROUP BY OBJECT_NAME(id) |
。
包括评论
我创建了一个在过程、表、视图或作业中搜索文本的过程。第一个参数@search是搜索条件,@target是搜索目标,即过程、表等。如果未指定,则搜索全部。@db指定要搜索的数据库,如果未指定,则使用当前db。下面是动态SQL中的查询。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | ALTER PROCEDURE [dbo].[usp_find_objects] ( @SEARCH VARCHAR(255), @target VARCHAR(255) = NULL, @db VARCHAR(35) = NULL ) AS SET NOCOUNT ON; DECLARE @TSQL NVARCHAR(MAX), @USEDB NVARCHAR(50) IF @db <> '' SET @USEDB = 'USE ' + @db ELSE SET @USEDB = '' IF @target IS NULL SET @target = '' SET @TSQL = @USEDB + ' DECLARE @search VARCHAR(128) DECLARE @target VARCHAR(128) SET @search = ''%' + @SEARCH + '%'' SET @target = ''' + @target + ''' IF @target LIKE ''%Procedure%'' BEGIN SELECT o.name As ''Stored Procedures'' FROM SYSOBJECTS o INNER JOIN SYSCOMMENTS c ON o.id = c.id WHERE c.text LIKE @search AND o.xtype = ''P'' GROUP BY o.name ORDER BY o.name END ELSE IF @target LIKE ''%View%'' BEGIN SELECT o.name As ''Views'' FROM SYSOBJECTS o INNER JOIN SYSCOMMENTS c ON o.id = c.id WHERE c.text LIKE @search AND o.xtype = ''V'' GROUP BY o.name ORDER BY o.name END /* Table - search table name only, need to add column name */ ELSE IF @target LIKE ''%Table%'' BEGIN SELECT t.name AS ''TableName'' FROM sys.columns c JOIN sys.tables t ON c.object_id = t.object_id WHERE c.name LIKE @search ORDER BY TableName END ELSE IF @target LIKE ''%Job%'' BEGIN SELECT j.job_id, s.srvname, j.name, js.step_id, js.command, j.enabled FROM [msdb].dbo.sysjobs j JOIN [msdb].dbo.sysjobsteps js ON js.job_id = j.job_id JOIN master.dbo.sysservers s ON s.srvid = j.originating_server_id WHERE js.command LIKE @search END ELSE BEGIN SELECT o.name As ''Stored Procedures'' FROM SYSOBJECTS o INNER JOIN SYSCOMMENTS c ON o.id = c.id WHERE c.text LIKE @search AND o.xtype = ''P'' GROUP BY o.name ORDER BY o.name SELECT o.name As ''Views'' FROM SYSOBJECTS o INNER JOIN SYSCOMMENTS c ON o.id = c.id WHERE c.text LIKE @search AND o.xtype = ''V'' GROUP BY o.name ORDER BY o.name SELECT t.name AS ''Tables'' FROM sys.columns c JOIN sys.tables t ON c.object_id = t.object_id WHERE c.name LIKE @search ORDER BY Tables SELECT j.name AS ''Jobs'' FROM [msdb].dbo.sysjobs j JOIN [msdb].dbo.sysjobsteps js ON js.job_id = j.job_id JOIN master.dbo.sysservers s ON s.srvid = j.originating_server_id WHERE js.command LIKE @search END ' EXECUTE sp_executesql @TSQL |
号
使用charindex:
1 2 3 4 5 | SELECT DISTINCT o.name AS Object_Name,o.type_desc FROM sys.sql_modules m INNER JOIN sys.objects o ON m.object_id=o.object_id WHERE CHARINDEX('[ABD]',m.definition) >0 ; |
使用patindex:
1 2 3 4 5 | SELECT DISTINCT o.name AS Object_Name,o.type_desc FROM sys.sql_modules m INNER JOIN sys.objects o ON m.object_id=o.object_id WHERE PATINDEX('[[]ABD]',m.definition) >0 ; |
。
使用这个双
1 | WHERE m.definition LIKE '%[[]ABD]%' |
也可以尝试:
1 2 3 | SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_DEFINITION LIKE '%\[ABD\]%' |
。
1 2 3 4 5 6 7 8 9 10 | SELECT DISTINCT OBJECT_NAME([id])--,syscomments.* this gives name of --stored procedures that text found FROM syscomments WHERE [id] IN (SELECT [id] FROM sysobjects WHERE xtype IN ('TF','FN','V','P') AND STATUS >= 0) AND ([text] LIKE '%text to be search%' ) |
号
对象名([id])->对象名(视图、存储过程、标量函数、表函数名)
id(int)=object标识号
xtype char(2)对象类型。可以是以下对象类型之一:
fn=标量函数
P=存储过程
V=视图
tf=表函数
1 | SELECT DISTINCT OBJECT_NAME(id) FROM syscomments WHERE text LIKE '%string%' AND OBJECTPROPERTY(id, 'IsProcedure') = 1 |
号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | /* SEARCH SPROCS & VIEWS The following query will allow search within the definitions of stored procedures and views. It spits out the results as XML, with the full definitions, so you can browse them without having to script them individually. */ /* STEP 1: POPULATE SEARCH KEYS. (Set to NULL to ignore) */ DECLARE @def_key VARCHAR(128) = '%foo%', /* <<< definition search key */ @name_key VARCHAR(128) = '%bar%', /* <<< name search key */ @schema_key VARCHAR(128) = 'dbo'; /* <<< schema search key */ ;WITH SearchResults AS ( /* STEP 2: DEFINE SEARCH QUERY AS CTE (Common Table Expression) */ SELECT [Object].object_id AS [object_id], [Schema].name AS [schema_name], [Object].name AS [object_name], [Object].type AS [object_type], [Object].type_desc AS [object_type_desc], [Details].definition AS [module_definition] FROM /* sys.sql_modules = where the body of sprocs and views live */ sys.sql_modules AS [Details] WITH (NOLOCK) JOIN /* sys.objects = where the metadata for every object in the database lives */ sys.objects AS [Object] WITH (NOLOCK) ON [Details].object_id = [Object].object_id JOIN /* sys.schemas = where the schemas in the datatabase live */ sys.schemas AS [Schema] WITH (NOLOCK) ON [Object].schema_id = [Schema].schema_id WHERE (@def_key IS NULL OR [Details].definition LIKE @def_key) /* <<< searches definition */ AND (@name_key IS NULL OR [Object].name LIKE @name_key) /* <<< searches name */ AND (@schema_key IS NULL OR [Schema].name LIKE @schema_key) /* <<< searches schema */ ) /* STEP 3: SELECT FROM CTE INTO XML */ /* This outer select wraps the inner queries in to the <sql_object> root element */ SELECT ( /* This inner query maps stored procedure rows to <procedure> elements */ SELECT TOP 100 PERCENT [object_id] AS [@object_id], [schema_name] + '.' + [object_name] AS [@full_name], [module_definition] AS [module_definition] FROM SearchResults WHERE object_type = 'P' ORDER BY [schema_name], [object_name] FOR XML PATH ('procedure'), TYPE ) AS [procedures], /* <<< as part of the outer query, this alias causes the <procedure> elements to be wrapped within the <procedures> element */ ( /* This inner query maps view rows to <view> elements */ SELECT TOP 100 PERCENT [object_id] AS [@object_id], [schema_name] + '.' + [object_name] AS [@full_name], [module_definition] AS [module_definition] FROM SearchResults WHERE object_type = 'V' ORDER BY [schema_name], [object_name] FOR XML PATH ('view'), TYPE ) AS [views] /* <<< as part of the outer query, this alias causes the <view> elements to be wrapped within the <views> element */ FOR XML PATH ('sql_objects') |
号
每隔一段时间,我都会使用这个脚本来找出要修改的进程,或者找出使用表中的某一列来删除旧的垃圾的方法。它会检查运行它的实例上的每个数据库,这些数据库由提供极好的sp msforeachdb运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | IF object_id('tempdb..##nothing') IS NOT NULL DROP TABLE ##nothing CREATE TABLE ##nothing ( DatabaseName VARCHAR(30), SchemaName VARCHAR(30), ObjectName VARCHAR(100), ObjectType VARCHAR(50) ) EXEC master.sys.sp_msforeachdb 'USE ? insert into ##nothing SELECT db_name() AS [Database], [Scehma]=schema_name(o.schema_id), o.Name, o.type FROM sys.sql_modules m INNER JOIN sys.objects o ON o.object_id = m.object_id WHERE m.definition like ''%SOME_TEXT%''' --edit this text SELECT * FROM ##nothing n ORDER BY OBJECTname |
号
1 2 3 4 5 6 7 8 9 10 11 | -- Applicable for SQL 2005+ USE YOUR_DATABASE_NAME //; GO SELECT [Scehma] = schema_name(o.schema_id) ,o.NAME ,o.type FROM sys.sql_modules m INNER JOIN sys.objects o ON o.object_id = m.object_id WHERE m.DEFINITION LIKE '%YOUR SEARCH KEYWORDS%' GO |
号
此查询是存储过程中所有数据库的搜索文本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | DECLARE @T_Find_Text VARCHAR(1000) = 'Foo' IF OBJECT_ID('tempdb..#T_DBNAME') IS NOT NULL DROP TABLE #T_DBNAME IF OBJECT_ID('tempdb..#T_PROCEDURE') IS NOT NULL DROP TABLE #T_PROCEDURE CREATE TABLE #T_DBNAME ( IDX INT IDENTITY(1,1) PRIMARY KEY , DBName VARCHAR(255) ) CREATE TABLE #T_PROCEDURE ( IDX INT IDENTITY(1,1) PRIMARY KEY , DBName VARCHAR(255) , Procedure_Name VARCHAR(MAX) , Procedure_Description VARCHAR(MAX) ) INSERT INTO #T_DBNAME (DBName) SELECT name FROM master.dbo.sysdatabases DECLARE @T_C_IDX INT = 0 DECLARE @T_C_DBName VARCHAR(255) DECLARE @T_SQL NVARCHAR(MAX) DECLARE @T_SQL_PARAM NVARCHAR(MAX) SET @T_SQL_PARAM = ' @T_C_DBName VARCHAR(255) , @T_Find_Text VARCHAR(255) ' WHILE EXISTS(SELECT TOP 1 IDX FROM #T_DBNAME WHERE IDX > @T_C_IDX ORDER BY IDX ASC) BEGIN SELECT TOP 1 @T_C_DBName = DBName FROM #T_DBNAME WHERE IDX > @T_C_IDX ORDER BY IDX ASC SET @T_SQL = '' SET @T_SQL = @T_SQL + 'INSERT INTO #T_PROCEDURE(DBName, Procedure_Name, Procedure_Description)' SET @T_SQL = @T_SQL + 'SELECT SPECIFIC_CATALOG, ROUTINE_NAME, ROUTINE_DEFINITION ' SET @T_SQL = @T_SQL + 'FROM ' + @T_C_DBName + '.INFORMATION_SCHEMA.ROUTINES ' SET @T_SQL = @T_SQL + 'WHERE ROUTINE_DEFINITION LIKE ''%''+ @T_Find_Text + ''%'' ' SET @T_SQL = @T_SQL + 'AND ROUTINE_TYPE = ''PROCEDURE'' ' BEGIN TRY EXEC SP_EXECUTESQL @T_SQL, @T_SQL_PARAM, @T_C_DBName, @T_Find_Text END TRY BEGIN CATCH SELECT @T_C_DBName + ' ERROR' END CATCH SET @T_C_IDX = @T_C_IDX + 1 END SELECT IDX, DBName, Procedure_Name FROM #T_PROCEDURE ORDER BY DBName ASC |
您也可以使用
1 2 3 4 5 6 7 8 9 10 11 | CREATE PROCEDURE [SEARCH]( @FILTER nvarchar(MAX) ) AS BEGIN SELECT name FROM procedures WHERE definition LIKE '%'+@FILTER+'%' END |
然后跑
1 | EXEC [SEARCH] 'text' |
。