Wyszukaj tekst w procedurze przechowywanej w SQL Server


820

Chcę wyszukać tekst ze wszystkich procedur przechowywanych w bazie danych. Używam poniższego kodu 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]%';

Chcę wyszukiwać [ABD]we wszystkich procedurach przechowywanych, w tym w nawiasach kwadratowych, ale nie daje to właściwego wyniku. Jak mogę zmienić moje zapytanie, aby to osiągnąć?

Odpowiedzi:


570

Unikaj nawiasów kwadratowych:

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

Wówczas nawiasy kwadratowe będą traktowane jak literały łańcuchowe, a nie jako symbole wieloznaczne.


nie podawaj nazwy schematu :(
Imad

4
@Imad Nazwę schematu można uzyskać, dodając SCHEMA_NAME(o.schema_id) AS Schema_Namedo klauzuli select.
patricus

6
Nie działa to z dłuższymi procedurami przechowywanymi. Zamiast tego użyj poniżej kodu Ullas.
Charles Graham

3
Dowiedziałem się na własnej skórze, że ta odpowiedź przeszuka tylko pierwsze 4000 znaków tekstu procedury składowanej. Sprawdź ten link, aby uzyskać prawdziwą odpowiedź. sqlhints.com/2011/10/01/…
Hunter Nelson

Tak samo tutaj, information_schema nie przeszukiwał zawartości-tekstu (w SProcs), zamiast tego zadziałało dla mnie użycie „sys.procedures”. Rozumiem, że Microsoft zaleca użycie schematu informacji, jednak najwyraźniej nie działa to dla wielu, dlatego Microsoft powinien przyjrzeć się temu problemowi.
Eddie Kumar,

319

Spróbuj tego żądania:

Pytanie

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

56

Czy próbowałeś użyć narzędzi innych firm do wyszukiwania? Istnieje kilka dostępnych na rynku, które są bezpłatne i pozwoliły mi zaoszczędzić mnóstwo czasu w przeszłości.

Poniżej znajdują się dwa dodatki SSMS, z których korzystałem.

Wyszukiwanie ApexSQL - przeszukuje zarówno schemat, jak i dane w bazach danych oraz ma dodatkowe funkcje, takie jak śledzenie zależności i więcej…

Pakiet narzędzi SSMS - ma taką samą funkcjonalność wyszukiwania jak poprzednia i kilka innych ciekawych funkcji. Nie jest darmowy dla SQL Server 2012, ale wciąż bardzo przystępny.

Wiem, że ta odpowiedź nie jest w 100% związana z pytaniami (która była bardziej szczegółowa), ale mam nadzieję, że inni uznają ją za przydatną.


35

Zazwyczaj wykonuję następujące czynności, aby to osiągnąć:

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

31

Dobra praktyka do pracy z SQL Server.

Utwórz poniżej procedury składowanej i ustaw krótki klawisz,

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

Teraz - Ustaw krótki klawisz jak poniżej,

wprowadź opis zdjęcia tutaj

Więc następnym razem, gdy chcesz znaleźć konkretny tekst w dowolnym z czterech obiektów, takich jak Store procedure, Views, Functionsi Tables. Wystarczy wpisać to słowo kluczowe i nacisnąć klawisz skrótu.

Na przykład: chcę wyszukać „PaymentTable”, a następnie napisać „PaymentTable” i upewnić się, że wybrałeś lub podświetliłeś zapisane słowo kluczowe w edytorze zapytań i nacisnąłem klawisz skrótu ctrl+4- zapewni to pełny wynik.


W SSMS 18.2 (podłączony do platformy Azure) kod działa świetnie. Krótki klawisz zwraca Procedure or function 'Searchinall' expects parameter '@strFind', which was not suppliedJakieś pomysły?
gordon613

@ gordon613, czy wpisałeś słowo kluczowe do wyszukiwania, naciskając klawisz skrótu w SSMS? np. „Pracownik”, a następnie ctrl + 4
pedram

@ pedram. - dzięki! Teraz mam to działa - w mojej konfiguracji musisz wpisać słowo kluczowe, następnie je podświetlić, a następnie naciśnij CTRL + 4
gordon613

tak, musimy zaznaczyć / wybrać słowo kluczowe przed naciśnięciem CTRL + 4. Dzięki stary!
pedram

1
@AngelWarrior, Być może wypróbowałeś go w nowym zapytaniu i powinien był działać dla Ciebie. Mam na myśli, że nie ma potrzeby restartowania SSMS. Dziękujemy za udostępnienie ścieżki skrótów dla SSMS 18.2.
pedram


19

Proszę to potraktować jako „brudną” alternatywę, ale to uratowało mnie wiele razy, szczególnie gdy nie znałem projektu DB. Czasami próbujesz wyszukać ciąg znaków we wszystkich SP i zapominasz, że niektóre powiązane logiki mogły ukrywać się między funkcjami a wyzwalaczami lub mogą być po prostu inaczej sformułowane, niż ci się wydawało.

W MSSMS możesz kliknąć prawym przyciskiem myszy DB i wybrać Tasks -> Generate Scriptskreatora, aby wyprowadzić wszystkie SP, Fns i Triggery do jednego pliku .sql.

wprowadź opis zdjęcia tutaj

Pamiętaj, aby wybrać również wyzwalacze!

wprowadź opis zdjęcia tutaj

Następnie po prostu użyj Sublime lub Notatnika, aby wyszukać ciąg, który chcesz znaleźć. Wiem, że to może być dość nieefektywne i paranoiczne podejście, ale działa :)


12

Możesz także użyć tego:

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

9
-1 Minusem w porównaniu z innymi opcjami jest INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITIONtylko pierwsze 4000 znaków procedury.
Shannon Severance

8

To może ci pomóc!

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

Możesz także użyć:

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

Obejmuje to komentarze


3
Nie powinieneś używać systemów do tego celu. Pole tekstowe odcina się na 4000 znaków. Pole definicji z sys.sql_modules wydaje się przechowywać cały tekst (w każdym razie ponad 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]) -> Nazwa obiektu (widok, procedura przechowywania, funkcja skalarna, nazwa funkcji tabelowej)

id (int) = numer identyfikacyjny obiektu

xtype char (2) Typ obiektu. Może być jednym z następujących typów obiektów:

FN = funkcja skalarna

P = procedura składowana

V = widok

TF = funkcja tabeli


4

Stworzyłem procedurę wyszukiwania tekstu w procedurach / funkcjach, tabelach, widokach lub zadaniach. Pierwszy parametr @ szukaj to kryterium wyszukiwania, @ cel docelowy wyszukiwania, tzn. Procedury, tabele itp. Jeśli nie określono, wyszukaj wszystko. @db określa bazę danych do przeszukania, domyślnie w bieżącej bazie danych. Oto moje zapytanie w dynamicznym 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

Aktualizacja: jeśli zmienisz nazwę procedury, aktualizuje się ona tylko, sysobjectsale nie syscomments, co zachowuje starą nazwę, a zatem procedura ta nie zostanie uwzględniona w wyniku wyszukiwania, chyba że upuścisz i odtworzysz procedurę.


Kliknij ten link, aby wyszukać nazwę kolumny.
Weihui Guo

3

Za pomocą 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 ;

Za pomocą 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 ; 

Korzystanie z tego podwójnego [[]ABD]jest podobne do ucieczki:

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

3

spróbuj także:

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

1
Select distinct OBJECT_NAME(id) from syscomments where text like '%string%' AND OBJECTPROPERTY(id, 'IsProcedure') = 1 

1

To zapytanie wyszukuje tekst w procedurze przechowywanej ze wszystkich baz danych.

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

Od czasu do czasu używam tego skryptu, aby dowiedzieć się, które procesy zmodyfikować, lub dowiedzieć się, co wykorzystuje kolumnę tabeli lub tę tabelę, aby usunąć stare śmieci. Sprawdza każdą bazę danych w instancji, w której jest uruchamiany przez wspaniale dostarczony 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 

och, tak ... czy to tak!
Bitcoin Murderous Maniac

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

Możesz także użyć

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

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

END

a następnie biegnij

exec [Search] 'text'

W klauzuli WHERE brakuje odwołania do pola. Powinieneś również odwołać się do schematu (sys)
Roger Willcocks
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.