Шукати текст у збереженій процедурі на 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.
patricus

6
Це не працює при триваліших зберігаються процедурах. Використовуйте нижче SQL Ullas.
Чарльз Грем

3
Я зрозумів, що ця відповідь шукає лише перші 4000 символів тексту тексту, що зберігається. Перевірте це посилання для справжньої відповіді. sqlhints.com/2011/10/01/…
Мисливець Нельсон

Тут же інформація_схеми не шукала контент-текст (у SProcs), замість цього для мене працювало "sys.procedures". Я розумію, що Microsoft рекомендує використовувати information_schema, однак, мабуть, для багатьох це не працює, тому Microsoft має розглянути це питання.
Едді Кумар

319

Спробуйте цей запит:

Запит

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

56

Ви спробували скористатися деякими сторонніми інструментами для пошуку? Є кілька доступних там безкоштовних і це заощадило мені тону часу в минулому.

Нижче наведено два SSMS Addin, які я використовував з успіхом.

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 і тригери в один файл .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
Не слід використовувати для цього системні коментарі. Текстове поле обрізається на 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 - це критерій пошуку, @ орієнтуйте на ціль пошуку, тобто процедури, таблиці тощо. Якщо не вказано, шукайте всі. @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]%'

3

також спробуйте це:

   SELECT ROUTINE_NAME 
    FROM INFORMATION_SCHEMA.ROUTINES 
    WHERE ROUTINE_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.