Cerca il testo nella stored procedure in SQL Server


820

Voglio cercare un testo da tutte le procedure memorizzate nel mio database. Io uso il seguente 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]%';

Voglio cercare [ABD]in tutte le procedure memorizzate, comprese le parentesi quadre, ma non sta dando il risultato corretto. Come posso modificare la mia query per raggiungere questo obiettivo?

Risposte:


570

Sfuggire alle parentesi quadre:

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

Quindi le parentesi quadre saranno trattate come letterali di stringa e non come caratteri jolly.


non dare il nome dello schema :(
Imad

4
@Imad È possibile ottenere il nome dello schema aggiungendolo SCHEMA_NAME(o.schema_id) AS Schema_Namealla clausola select.
Patricus,

6
Questo non funziona con stored procedure più lunghe. Usa invece l'SQL di Ullas qui sotto.
Charles Graham,

3
Ho scoperto che questa risposta cercherà solo i primi 4000 caratteri del testo della procedura memorizzata. Dai un'occhiata a questo link per la vera risposta. sqlhints.com/2011/10/01/…
Hunter Nelson

Lo stesso qui, information_schema non ha cercato contenuto-testo (all'interno di SProcs), invece l'uso di "sys.procedures" ha funzionato per me. Comprendo che Microsoft raccomanda l'uso di information_schema, tuttavia a quanto pare questo non funziona per molti, quindi Microsoft dovrebbe esaminare questo problema.
Eddie Kumar,

319

Prova questa richiesta:

domanda

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

56

Hai provato a utilizzare alcuni degli strumenti di terze parti per eseguire la ricerca? Ci sono molti disponibili là fuori che sono gratuiti e che mi hanno risparmiato un sacco di tempo in passato.

Di seguito sono riportati due componenti aggiuntivi SSMS che ho usato con successo.

Ricerca ApexSQL - Cerca sia lo schema che i dati nei database e ha funzionalità aggiuntive come il rilevamento delle dipendenze e altro ...

Pacchetto strumenti SSMS : ha la stessa funzionalità di ricerca della precedente e molte altre interessanti funzioni. Non gratuito per SQL Server 2012 ma comunque molto conveniente.

So che questa risposta non è correlata al 100% alle domande (che era più specifica), ma spero che altri lo trovino utile.


35

Di solito eseguo quanto segue per farlo:

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

31

Buone pratiche per lavorare con SQL Server.

Creare la procedura memorizzata di seguito e impostare il tasto funzione,

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

Ora: imposta il tasto di scelta rapida come di seguito,

inserisci qui la descrizione dell'immagine

Così la prossima volta ogni volta che si vuole trovare un determinato testo in una qualsiasi delle quattro oggetti come Store procedure, Views, Functionse Tables. Devi solo scrivere quella parola chiave e premere il tasto di scelta rapida.

Ad esempio: desidero cercare "PaymentTable", quindi scrivere "PaymentTable" e assicurarmi di selezionare o evidenziare la parola chiave scritta nell'editor di query e premere il tasto di scelta rapida ctrl+4per fornire il risultato completo.


In SSMS v18.2 (connesso ad Azure) il codice funziona alla grande. Il tasto breve restituisce Procedure or function 'Searchinall' expects parameter '@strFind', which was not suppliedQualche idea?
gordon613

@ gordon613 hai digitato una parola chiave per la ricerca mentre premi il tasto di scelta rapida su SSMS? ad es. "Dipendente" e poi ctrl + 4
pedram

@ pedram.- grazie! Ora ho funzionato - sulla mia configurazione è necessario digitare la parola chiave, quindi evidenziarla e quindi premere CTRL + 4
gordon613

sì, dobbiamo evidenziare / selezionare la parola chiave prima di premere CTRL + 4. Grazie compagno!
pedram,

1
@AngelWarrior, potresti averlo provato con una nuova query e avrebbe dovuto funzionare per te. Voglio dire, non è necessario riavviare SSMS. Grazie per aver fornito il percorso delle scorciatoie per SSMS 18.2.
pedram,


19

Si prega di prendere questo come un'alternativa "sporca" ma questo mi ha salvato molte volte soprattutto quando non avevo familiarità con il progetto DB. A volte stai cercando di cercare una stringa all'interno di tutti gli SP e dimentichi che parte della logica correlata potrebbe essersi nascosta tra Funzioni e Trigger o può essere semplicemente formulata diversamente da come pensavi.

Dal tuo MSSMS puoi fare clic con il pulsante destro del mouse sul DB e selezionare la Tasks -> Generate Scriptsprocedura guidata per generare tutti gli SP, Fns e Trigger in un unico file .sql.

inserisci qui la descrizione dell'immagine

Assicurati di selezionare anche i trigger!

inserisci qui la descrizione dell'immagine

Quindi basta usare Sublime o Blocco note per cercare la stringa che devi trovare. So che questo può essere un approccio abbastanza inefficiente e paranoico, ma funziona :)


12

Puoi anche usare questo:

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

9
-1 L'aspetto negativo rispetto ad altre opzioni contiene INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITIONsolo i primi 4000 caratteri della routine.
Shannon Severance,

8

Potrebbe aiutarti!

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

Inoltre puoi usare:

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

Questo include commenti


3
Non dovresti usare syscomments per questo scopo. Il campo di testo è tagliato a 4000 caratteri. Il campo di definizione di sys.sql_modules sembra memorizzare l'intero testo (più di 4000 comunque)
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]) -> Nome oggetto (vista, procedura di memorizzazione, funzione scalare, nome funzione tabella)

id (int) = Numero identificativo oggetto

xtype char (2) Tipo di oggetto. Può essere uno dei seguenti tipi di oggetto:

FN = funzione scalare

P = Stored procedure

V = Visualizza

TF = Funzione tabella


4

Ho creato una procedura per cercare testo in procedure / funzioni, tabelle, viste o lavori. Il primo parametro @search è il criterio di ricerca, @target il target di ricerca, ovvero procedure, tabelle, ecc. Se non specificato, cerca tutto. @db è specificare il database da cercare, predefinito al database corrente. Ecco la mia query in SQL dinamico.

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

Aggiorna: se hai rinominato una procedura, questa si aggiorna sysobjectsma non syscommentsmantiene, il che mantiene il vecchio nome e quindi quella procedura non verrà inclusa nel risultato della ricerca a meno che non lasci cadere e ricreare la procedura.


Segui questo link per cercare il nome della colonna.
Weihui Guo,

3

Utilizzando 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 ;

Utilizzando 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 ; 

L'uso di questo doppio [[]ABD]è simile all'evasione:

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

3

prova anche questo:

   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

Questa query è il testo di ricerca nella stored procedure da tutti i database.

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

Ogni tanto uso questo script per capire quali processi modificare, o per capire cosa usa una colonna di una tabella, o quella tabella per rimuovere qualche vecchia spazzatura. Controlla ogni database sull'istanza su cui viene eseguito da sp_msforeachdb meravigliosamente fornito.

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, sì ... è così!
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

Puoi anche usare

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

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

END

e poi corri

exec [Search] 'text'

Nella clausola WHERE manca un riferimento al campo. Dovresti anche fare riferimento allo schema (sys)
Roger Willcocks,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.