【问题标题】:Search text in stored procedure in SQL Server在 SQL Server 的存储过程中搜索文本
【发布时间】:2013-01-20 04:15:43
【问题描述】:

我想从我的所有数据库存储过程中搜索文本。我使用下面的 SQL:

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]%';

我想在包括方括号在内的所有存储过程中搜索[ABD],但它没有给出正确的结果。如何更改我的查询以实现此目的?

【问题讨论】:

标签: sql sql-server stored-procedures


【解决方案1】:

转义方括号:

...
WHERE m.definition Like '%\[ABD\]%' ESCAPE '\'

然后方括号将被视为字符串文字而不是通配符。

【讨论】:

  • 不提供架构名称 :(
  • @Imad 可以通过在 select 子句中添加 SCHEMA_NAME(o.schema_id) AS Schema_Name 来获取架构名称。
  • 这不适用于更长的存储过程。请改用 Ullas 的 SQL。
  • 我发现这个答案只会搜索存储过程文本的前 4000 个字符。查看此链接以获得真正的答案。 sqlhints.com/2011/10/01/…
  • 同样,information_schema 没有搜索内容文本(在 SProcs 中),而是使用“sys.procedures”为我工作。我了解 Microsoft 建议使用 information_schema,但显然这对许多人不起作用,因此 Microsoft 应该研究这个问题。
【解决方案2】:

试试这个请求:

查询

SELECT name
FROM   sys.procedures
WHERE  Object_definition(object_id) LIKE '%strHell%'

【讨论】:

  • 我必须以管理员身份运行这项工作。
【解决方案3】:

您是否尝试过使用某些第三方工具进行搜索?那里有几个免费的,过去为我节省了大量时间。

以下是我成功使用的两个 SSMS 插件。

ApexSQL Search - 搜索数据库中的模式和数据,并具有附加功能,如依赖跟踪等......

SSMS Tools pack - 具有与前一个相同的搜索功能和其他几个很酷的功能。 SQL Server 2012 不是免费的,但仍然非常实惠。

我知道这个答案不是 100% 与问题相关(更具体),但希望其他人会发现这很有用。

【讨论】:

    【解决方案4】:

    我通常运行以下命令来实现:

    select distinct object_name(id) 
    from syscomments 
    where text like '%[ABD]%'
    order by object_name(id) 
    

    【讨论】:

    • 这很好,因为它不仅可以搜索存储过程,还可以搜索表的视图和定义等
    【解决方案5】:

    使用 SQL Server 的良好做法。

    在下面创建存储过程并设置快捷键,

    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
    

    现在 - 设置短键如下,

    因此,下次当您想在 Store procedureViewsFunctionsTables 等四个对象中的任何一个中查找特定文本时。您只需要编写该关键字并按快捷键即可。

    例如:我想搜索“PaymentTable”,然后输入“PaymentTable”,并确保您在查询编辑器中选择或突出显示所写的关键字并按下快捷键ctrl+4 - 它会为您提供完整的结果。

    【讨论】:

    • 在 SSMS v18.2(连接到 Azure)中,代码运行良好。短键返回Procedure or function 'Searchinall' expects parameter '@strFind', which was not supplied 有什么想法吗?
    • @gordon613 您在SSMS 上按快捷键时输入了关键字进行搜索吗?例如'员工',然后是 ctrl + 4
    • @pedram.- 谢谢!我现在已经开始工作了 - 在我的设置中,您需要输入关键字,然后突出显示它,然后然后按 CTRL+4
    • @AngelWarrior,您可能已经在新查询中尝试过它,它应该对您有用。我的意思是不需要重新启动 SSMS。感谢您为 SSMS 18.2 提供快捷方式路径。
    • 总是缺少一个搜索SQL 作业步骤。我见过很少有没有运行该搜索的情况,我们一直在寻找在您的查询涵盖的所有对象之外更新我们数据的东西。
    【解决方案6】:

    Redgate's SQL Search 是一个很好的工具,它是 SSMS 的免费插件。

    【讨论】:

      【解决方案7】:

      请将此视为“肮脏”的替代方案,但这多次拯救了我,尤其是当我不熟悉 DB 项目时。有时您试图在所有 SP 中搜索一个字符串,却忘记了某些相关逻辑可能已经隐藏在函数和触发器之间,或者它的措辞可能与您想象的不同。

      在您的 MSSMS 中,您可以右键单击您的数据库并选择 Tasks -> Generate Scripts 向导将所有 SP、Fns 和触发器输出到单个 .sql 文件中。

      确保也选择触发器!

      然后只需使用 Sublime 或 Notepad 搜索您需要查找的字符串。 我知道这可能是非常低效和偏执的方法,但它确实有效 :)

      【讨论】:

        【解决方案8】:

        你也可以用这个:

        SELECT * 
        FROM INFORMATION_SCHEMA.ROUTINES 
        WHERE ROUTINE_DEFINITION like '%Search_String%'
        

        【讨论】:

        • -1 与其他选项相比的缺点是INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITION 仅包含例程的前 4000 个字符。
        【解决方案9】:
        select top 10 * from
        sys.procedures
        where object_definition(object_id) like '%\[ABD\]%'
        

        【讨论】:

          【解决方案10】:

          也许对你有帮助!

          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
          

          【讨论】:

            【解决方案11】:

            你也可以使用:

            SELECT OBJECT_NAME(id) 
                FROM syscomments 
                WHERE [text] LIKE '%flags.%' 
                AND OBJECTPROPERTY(id, 'IsProcedure') = 1 
                GROUP BY OBJECT_NAME(id)
            

            这包括 cmets

            【讨论】:

            • 您不应为此目的使用 syscmets。文本字段在 4000 个字符处截断。来自 sys.sql_modules 的定义字段似乎存储了整个文本(反正超过 4000 个)
            【解决方案12】:
            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]%';
            

            【讨论】:

              【解决方案13】:
               SELECT DISTINCT OBJECT_NAME([id]),[text] 
              
               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%' ) 
              

              OBJECT_NAME([id]) --> 对象名(视图、存储过程、标量函数、表函数名)

              id (int) = 对象标识号

              xtype char(2) 对象类型。可以是以下对象类型之一:

              FN = 标量函数

              P = 存储过程

              V = 视图

              TF = 表函数

              【讨论】:

                【解决方案14】:

                我创建了一个过程来搜索过程/函数、表、视图或作业中的文本。第一个参数@search 是搜索条件,@target 是搜索目标,即过程、表等。如果没有指定,则搜索全部。 @db 是指定要搜索的数据库,默认为你当前的数据库。这是我在动态 SQL 中的查询。

                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 IN (''P'',''FN'')
                    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 IN (''P'',''FN'')
                    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
                

                更新: 如果您重命名了一个过程,它只会更新 sysobjects 而不会更新 syscomments,它会保留旧名称,因此除非您删除并重新创建该过程,否则该过程将不会包含在搜索结果中。

                【讨论】:

                • 关注link搜索列名。
                【解决方案15】:
                SELECT name , type_desc , create_date , modify_date
                FROM   sys.procedures 
                WHERE  Object_definition(object_id) LIKE '%High%'
                

                【讨论】:

                  【解决方案16】:

                  使用CHARINDEX

                  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

                  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 ; 
                  

                  使用这个 double [[]ABD] 类似于转义:

                  WHERE m.definition LIKE '%[[]ABD]%'
                  

                  【讨论】:

                    【解决方案17】:

                    也试试这个:

                       SELECT ROUTINE_NAME 
                        FROM INFORMATION_SCHEMA.ROUTINES 
                        WHERE ROUTINE_DEFINITION like '%\[ABD\]%'
                    

                    【讨论】:

                      【解决方案18】:

                      此查询是在所有数据库的存储过程中搜索文本。

                      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
                      

                      【讨论】:

                      • 效果很好——谢谢!!
                      【解决方案19】:
                      Select distinct OBJECT_NAME(id) from syscomments where text like '%string%' AND OBJECTPROPERTY(id, 'IsProcedure') = 1 
                      

                      【讨论】:

                        【解决方案20】:

                        不同的版本,使查询更适合不同的编码实践。

                        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 UPPER(M.DEFINITION) LIKE UPPER('%Your Text%');
                        

                        【讨论】:

                          【解决方案21】:
                          /* 
                              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')
                          

                          【讨论】:

                            【解决方案22】:

                            我经常使用这个脚本来确定要修改哪些 proc,或者确定什么使用表的列,或者根本不使用该表来删除一些旧垃圾。它通过提供的出色的 sp_msforeachdb 检查运行它的实例上的每个数据库。

                            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 
                            

                            【讨论】:

                            • 哦,你……是这样的!
                            【解决方案23】:
                            -- 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
                            

                            【讨论】:

                              【解决方案24】:

                              你也可以使用

                              CREATE PROCEDURE [Search](
                                  @Filter nvarchar(max)
                              )
                              AS
                              BEGIN
                              
                              SELECT name
                              FROM   procedures
                              WHERE   definition LIKE '%'+@Filter+'%'
                              
                              END
                              

                              然后运行

                              exec [Search] 'text'
                              

                              【讨论】:

                              • WHERE 子句缺少字段引用。您还应该参考架构 (sys)
                              猜你喜欢
                              • 2011-06-03
                              • 1970-01-01
                              • 2011-06-29
                              • 1970-01-01
                              • 2012-02-22
                              • 2019-01-21
                              • 1970-01-01
                              • 2012-05-03
                              • 1970-01-01
                              相关资源
                              最近更新 更多