Поиск текста в хранимой процедуре в SQL Server


820

Я хочу найти текст во всех хранимых процедурах моей базы данных. Я использую ниже 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]во всех хранимых процедурах, включая квадратные скобки, но это не дает должного результата. Как я могу изменить свой запрос для достижения этого?

Ответы:


570

Избегайте квадратных скобок:

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

Тогда квадратные скобки будут рассматриваться как строковые литералы, а не как символы подстановки.


не дают имя схемы :(
Имад

4
@Imad Вы можете получить имя схемы, добавив SCHEMA_NAME(o.schema_id) AS Schema_Nameк предложению select.
Патрик

6
Это не работает с более длинными хранимыми процедурами. Вместо этого используйте SQL Уллы ниже.
Чарльз Грэм

3
Я обнаружил, что этот ответ будет искать только первые 4000 символов текста хранимой процедуры. Проверьте эту ссылку для реального ответа. sqlhints.com/2011/10/01/…
Охотник Нельсон

То же самое здесь, information_schema не искала контент-текст (в пределах SProcs), вместо этого использование «sys.procedures» работало для меня. Я понимаю, что Microsoft рекомендует использовать information_schema, однако, очевидно, что это не работает для многих, поэтому Microsoft следует изучить эту проблему.
Эдди Кумар,

320

Попробуйте этот запрос:

запрос

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

56

Вы пытались использовать некоторые сторонние инструменты для поиска? Есть несколько доступных там, которые бесплатны и которые сэкономили мне массу времени в прошлом.

Ниже приведены два дополнения SSMS, которые я использовал с хорошим успехом.

ApexSQL Search - выполняет поиск по схеме и данным в базах данных и имеет дополнительные функции, такие как отслеживание зависимостей и многое другое…

Пакет инструментов SSMS - имеет те же функции поиска, что и предыдущий, и несколько других интересных функций. Не бесплатно для SQL Server 2012, но все еще очень доступно.

Я знаю, что этот ответ не на 100% связан с вопросами (который был более конкретным), но, надеюсь, другие найдут это полезным.


35

Я обычно запускаю следующее для достижения этой цели:

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

31

Хорошая практика для работы с 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 procedure, Views, Functionsи Tables. Вам просто нужно написать это ключевое слово и нажать клавишу быстрого доступа.

Например: я хочу найти «PaymentTable», затем написать «PaymentTable» и убедиться, что вы выбрали или выделите написанное ключевое слово в редакторе запросов и нажали комбинацию клавиш ctrl+4- это даст вам полный результат.


В SSMS v18.2 (подключен к Azure) код работает отлично. Короткий ключ возвращает Procedure or function 'Searchinall' expects parameter '@strFind', which was not suppliedЛюбые идеи?
gordon613

@ gordon613 вы ввели ключевое слово для поиска при нажатии клавиши быстрого доступа в SSMS? например, «Сотрудник», а затем Ctrl + 4
Pedram

@ pedram.- спасибо! Теперь у меня все работает - в моей настройке вам нужно ввести ключевое слово, затем выделить его, а затем нажать CTRL + 4
gordon613

да, нам нужно выделить / выбрать ключевое слово перед нажатием CTRL + 4. Спасибо друг!
Педрам

1
@AngelWarrior, возможно, вы пробовали это в новом запросе, и это должно сработать для вас. Я имею в виду не нужно перезагружать SSMS. Спасибо за предоставление пути ярлыков для SSMS 18.2.
Педрам


19

Пожалуйста, примите это как «грязную» альтернативу, но это спасло меня много раз, особенно когда я не был знаком с проектом БД. Иногда вы пытаетесь найти строку во всех SP и забываете, что некоторая связанная логика могла скрываться между функциями и триггерами, или она может быть просто сформулирована иначе, чем вы думали.

В вашей MSSMS вы можете щелкнуть правой кнопкой мыши по вашей БД и выбрать Tasks -> Generate Scriptsмастер, чтобы вывести все SP, Fns и Trigger в один файл .sql.

введите описание изображения здесь

Обязательно выберите Триггеры тоже!

введите описание изображения здесь

Затем просто используйте Sublime или Notepad для поиска нужной вам строки. Я знаю, что это может быть довольно неэффективным и параноидальным подходом, но это работает :)


12

Вы также можете использовать это:

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

9
-1 Недостаток по сравнению с другими вариантами - это INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITIONтолько первые 4000 символов рутины.
Шеннон Северанс

8

Это может помочь вам!

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


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

5

Также вы можете использовать:

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

Это включает в себя комментарии


3
Вы не должны использовать syscomments для этой цели. Текстовое поле обрезается на 4000 символов. Поле определения из sys.sql_modules, похоже, хранит весь текст (более 4000)
jlnorsworthy

5
 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 = табличная функция


4

Я создал процедуру для поиска текста в процедурах / функциях, таблицах, представлениях или заданиях. Первый параметр @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, что сохраняет старое имя и, следовательно, эта процедура не будет включена в результат поиска, если вы не удалите и не создадите заново процедуру.


Перейдите по этой ссылке, чтобы найти имя столбца.
Вэйхуэй Го

3

Используя 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 ; 

Использование этого двойника [[]ABD]похоже на экранирование:

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



1

Этот запрос является поиском текста в хранимой процедуре из всех баз данных.

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

0
/* 
    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')

0

Время от времени я использую этот сценарий, чтобы выяснить, какие процедуры нужно изменить, или выяснить, что вообще использует столбец таблицы или эту таблицу, чтобы удалить какой-то старый мусор. Он проверяет каждую базу данных в экземпляре, на котором она запущена чудесным образом предоставленным 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 


0
-- 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

-2

Вы также можете использовать

CREATE PROCEDURE [Search](
    @Filter nvarchar(max)
)
AS
BEGIN

SELECT name
FROM   procedures
WHERE   definition LIKE '%'+@Filter+'%'

END

а потом беги

exec [Search] 'text'

В предложении WHERE отсутствует ссылка на поле. Вам также следует ссылаться на схему (sys)
Роджер Уиллкокс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.