Suchen Sie nach Text in einer gespeicherten Prozedur in SQL Server


820

Ich möchte einen Text aus allen gespeicherten Datenbankprozeduren suchen. Ich benutze das folgende 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]%';

Ich möchte [ABD]in allen gespeicherten Prozeduren einschließlich eckiger Klammern suchen , aber es gibt nicht das richtige Ergebnis. Wie kann ich meine Abfrage ändern, um dies zu erreichen?

Antworten:


570

Entkomme den eckigen Klammern:

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

Dann werden die eckigen Klammern als Zeichenfolgenliterale und nicht als Platzhalter behandelt.


Geben Sie keinen Schemanamen an :(
Imad

4
@Imad Sie können den Schemanamen abrufen, indem Sie ihn SCHEMA_NAME(o.schema_id) AS Schema_Namezur select-Klausel hinzufügen .
Patrickus

6
Dies funktioniert nicht mit länger gespeicherten Prozeduren. Verwenden Sie stattdessen Ullas 'SQL unten.
Charles Graham

3
Ich habe auf die harte Tour herausgefunden, dass diese Antwort nur die ersten 4000 Zeichen des gespeicherten Prozedurtextes durchsucht. Schauen Sie sich diesen Link an, um die richtige Antwort zu erhalten. sqlhints.com/2011/10/01/…
Hunter Nelson

Ebenso suchte information_schema nicht nach Inhaltstext (innerhalb von SProcs), sondern die Verwendung von "sys.procedures" funktionierte für mich. Ich verstehe, dass Microsoft die Verwendung von information_schema empfiehlt, aber anscheinend funktioniert dies bei vielen nicht, daher sollte Microsoft dieses Problem untersuchen.
Eddie Kumar

319

Versuchen Sie diese Anfrage:

Abfrage

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

56

Haben Sie versucht, einige Tools von Drittanbietern für die Suche zu verwenden? Es gibt mehrere, die kostenlos sind und mir in der Vergangenheit eine Menge Zeit gespart haben.

Unten sind zwei SSMS-Addins aufgeführt, die ich mit gutem Erfolg verwendet habe.

ApexSQL Search - Durchsucht sowohl Schema als auch Daten in Datenbanken und bietet zusätzliche Funktionen wie Abhängigkeitsverfolgung und mehr…

SSMS Tools Pack - Hat die gleiche Suchfunktion wie die vorherige und mehrere andere coole Funktionen. Nicht kostenlos für SQL Server 2012, aber dennoch sehr erschwinglich.

Ich weiß, dass diese Antwort nicht zu 100% mit den Fragen zusammenhängt (was spezifischer war), aber hoffentlich finden andere dies nützlich.


35

Normalerweise führe ich Folgendes aus, um dies zu erreichen:

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

31

Gute Praxis für die Arbeit mit SQL Server.

Erstellen Sie die unten gespeicherte Prozedur und setzen Sie den Kurzschlüssel.

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

Jetzt - Stellen Sie die Kurztaste wie folgt ein:

Geben Sie hier die Bildbeschreibung ein

Also das nächste Mal , wenn Sie wollen , wie einen bestimmten Text in einem der vier Objekte finden Store procedure, Views, Functionsund Tables. Sie müssen nur dieses Schlüsselwort schreiben und die Tastenkombination drücken.

Beispiel: Ich möchte nach "PaymentTable" suchen und dann "PaymentTable" schreiben und sicherstellen, dass Sie das geschriebene Schlüsselwort im Abfrageeditor auswählen oder markieren und die Tastenkombination drücken ctrl+4. Dadurch erhalten Sie das vollständige Ergebnis.


In SSMS v18.2 (verbunden mit Azure) funktioniert der Code hervorragend. Der Kurzschlüssel gibt zurück Procedure or function 'Searchinall' expects parameter '@strFind', which was not suppliedIrgendwelche Ideen?
gordon613

@ gordon613 Haben Sie ein Schlüsselwort für die Suche eingegeben, während Sie die Tastenkombination auf SSMS gedrückt haben? zB 'Mitarbeiter' und dann Strg + 4
Pedram

@ pedram.- danke! Ich habe es jetzt zum
Laufen gebracht

Ja, wir müssen das Schlüsselwort markieren / auswählen, bevor wir STRG + 4 drücken. Danke Kumpel!
Pedram

1
@AngelWarrior, Sie haben es möglicherweise in einer neuen Abfrage versucht und es hätte für Sie funktionieren sollen. Ich meine, das SSMS muss nicht neu gestartet werden. Vielen Dank, dass Sie den Shortcuts-Pfad für SSMS 18.2 angegeben haben.
Pedram


19

Bitte nehmen Sie dies als "schmutzige" Alternative, aber dies hat mich viele Male gerettet, besonders wenn ich mit dem DB-Projekt nicht vertraut war. Manchmal versuchen Sie, in allen SPs nach einer Zeichenfolge zu suchen, und vergessen, dass sich ein Teil der zugehörigen Logik möglicherweise zwischen Funktionen und Triggern versteckt hat oder einfach anders formuliert ist, als Sie gedacht haben.

In Ihrem MSSMS können Sie mit der rechten Maustaste auf Ihre Datenbank klicken und den Tasks -> Generate ScriptsAssistenten auswählen, um alle SPs, Fns und Trigger in einer einzigen SQL-Datei auszugeben.

Geben Sie hier die Bildbeschreibung ein

Stellen Sie sicher, dass Sie auch Trigger auswählen!

Geben Sie hier die Bildbeschreibung ein

Verwenden Sie dann einfach Sublime oder Notepad , um nach der Zeichenfolge zu suchen, die Sie suchen müssen. Ich weiß, dass dies ein ziemlich ineffizienter und paranoider Ansatz ist, aber er funktioniert :)


12

Sie können auch dieses verwenden:

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

9
-1 Nachteil im Vergleich zu anderen Optionen sind INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITIONnur die ersten 4000 Zeichen der Routine.
Shannon Severance

8

Es könnte dir helfen!

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

7
select top 10 * from
sys.procedures
where object_definition(object_id) like '%\[ABD\]%'

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

Sie können auch verwenden:

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

Das beinhaltet Kommentare


3
Sie sollten zu diesem Zweck keine Systemkommentare verwenden. Das Textfeld wird mit 4000 Zeichen abgeschnitten. Das Definitionsfeld von sys.sql_modules scheint den gesamten Text zu speichern (sowieso mehr als 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]) -> Objektname (Ansicht, Speicherprozedur, Skalarfunktion, Name der Tabellenfunktion)

id (int) = Objektidentifikationsnummer

xtype char (2) Objekttyp. Kann einer der folgenden Objekttypen sein:

FN = Skalarfunktion

P = Gespeicherte Prozedur

V = Ansicht

TF = Tabellenfunktion


4

Ich habe eine Prozedur zum Suchen von Text in Prozeduren / Funktionen, Tabellen, Ansichten oder Jobs erstellt. Der erste Parameter @search ist das Suchkriterium, @target das Suchziel, dh Prozeduren, Tabellen usw. Wenn nicht angegeben, suchen Sie alle. @db gibt die zu durchsuchende Datenbank an, standardmäßig Ihre aktuelle Datenbank. Hier ist meine Abfrage in dynamischem 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

Aktualisieren: Wenn Sie eine Prozedur umbenannt haben, wird sie nur aktualisiert, sysobjectsjedoch nicht. Dabei syscommentswird der alte Name beibehalten. Daher wird diese Prozedur nur dann in das Suchergebnis aufgenommen, wenn Sie die Prozedur löschen und neu erstellen.


Folgen Sie diesem Link , um den Spaltennamen zu suchen.
Weihui Guo

3

Verwenden von 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 ;

Verwenden von 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 ; 

Die Verwendung dieses Doppels [[]ABD]ähnelt der Flucht:

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

3

Versuchen Sie auch Folgendes:

   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

Diese Abfrage ist Suchtext in gespeicherter Prozedur aus allen Datenbanken.

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

Von Zeit zu Zeit verwende ich dieses Skript, um herauszufinden, welche Prozesse geändert werden müssen, oder um herauszufinden, was eine Tabellenspalte oder diese Tabelle überhaupt verwendet, um alten Müll zu entfernen. Es überprüft jede Datenbank auf der Instanz, auf der sie ausgeführt wird, von der wunderbar bereitgestellten 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 

oh ja ... ist das so!
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

Sie können auch verwenden

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

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

END

und dann laufen

exec [Search] 'text'

In der WHERE-Klausel fehlt eine Feldreferenz. Sie sollten auch auf das Schema (sys) verweisen
Roger Willcocks
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.