Pesquisar texto no procedimento armazenado no SQL Server


820

Quero pesquisar um texto de todos os meus procedimentos armazenados no banco de dados. Eu uso o SQL abaixo:

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

Quero pesquisar [ABD]em todos os procedimentos armazenados, incluindo colchetes, mas não está dando o resultado adequado. Como posso alterar minha consulta para conseguir isso?

Respostas:


570

Escape dos colchetes:

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

Os colchetes serão tratados como literais de sequência e não como curingas.


não dê o nome do esquema :(
Imad

4
@Imad Você pode obter o nome do esquema adicionando SCHEMA_NAME(o.schema_id) AS Schema_Nameà cláusula select.
Patricus

6
Isso não funciona com procedimentos armazenados mais longos. Use o SQL de Ullas abaixo.
Charles Graham

3
Descobri da maneira mais difícil que esta resposta pesquisará apenas os primeiros 4000 caracteres do texto do procedimento armazenado. Confira este link para a resposta real. sqlhints.com/2011/10/01/…
Hunter Nelson

O mesmo aqui, information_schema não pesquisou conteúdo-texto (no SProcs), mas o uso de "sys.procedures" funcionou para mim. Entendo que a Microsoft recomenda o uso de information_schema, no entanto, aparentemente, isso não está funcionando para muitos, portanto, a Microsoft deve analisar esse problema.
Eddie Kumar

319

Tente este pedido:

Inquerir

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

56

Você já tentou usar algumas das ferramentas de terceiros para fazer a pesquisa? Existem vários disponíveis por aí que são gratuitos e que me salvaram uma tonelada de tempo no passado.

Abaixo estão dois suplementos do SSMS que usei com bom sucesso.

Pesquisa ApexSQL - Pesquisa o esquema e os dados nos bancos de dados e possui recursos adicionais, como rastreamento de dependências e mais…

Pacote de ferramentas SSMS - possui a mesma funcionalidade de pesquisa que a anterior e vários outros recursos interessantes. Não é gratuito para o SQL Server 2012, mas ainda é muito acessível.

Eu sei que esta resposta não está 100% relacionada às perguntas (que eram mais específicas), mas espero que outras pessoas achem isso útil.


35

Eu costumo executar o seguinte para conseguir isso:

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

31

Boas práticas para trabalhar com o SQL Server.

Crie o procedimento armazenado abaixo e defina a tecla de atalho,

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

Agora - defina a tecla de atalho como abaixo,

insira a descrição da imagem aqui

Da próxima vez, sempre que você quiser encontrar um texto específico em qualquer um dos quatro objetos Store procedure, como Views, Functionse Tables. Você só precisa escrever essa palavra-chave e pressionar a tecla de atalho.

Por exemplo: desejo pesquisar 'PaymentTable', depois escrever 'PaymentTable' e selecionar ou destacar a palavra-chave escrita no editor de consultas e pressionar a tecla de atalho ctrl+4- ele fornecerá o resultado completo.


No SSMS v18.2 (conectado ao Azure), o código funciona muito bem. A tecla de atalho retorna Procedure or function 'Searchinall' expects parameter '@strFind', which was not suppliedAlguma idéia?
gordon613

@ gordon613 você digitou a palavra-chave para pesquisar enquanto pressionava a tecla de atalho no SSMS? por exemplo, 'Funcionário' e, em seguida, ctrl + 4
pedram 01/04

@ pedram.- obrigado! Eu já tenho que trabalhar - na minha configuração que você precisa digitar a palavra-chave, então destacá-lo e , em seguida, pressione CTRL + 4
gordon613

sim, precisamos destacar / selecionar a palavra-chave antes de pressionar CTRL + 4. Obrigado companheiro!
pedram 01/04

1
@ AngelWarrior, você pode ter tentado em uma nova consulta e deveria ter funcionado para você. Quero dizer, não há necessidade de reiniciar o SSMS. Obrigado por fornecer o caminho de atalhos para o SSMS 18.2.
pedram


19

Por favor, tome isso como uma alternativa "suja", mas isso me salvou muitas vezes, especialmente quando eu não estava familiarizado com o projeto DB. Às vezes, você está tentando procurar uma cadeia de caracteres em todos os SPs e esquece que parte da lógica relacionada pode estar oculta entre Funções e Acionadores ou pode ser simplesmente redigida de maneira diferente do que você pensava.

No MSSMS, você pode clicar com o botão direito do mouse no seu DB e selecionar o Tasks -> Generate Scriptsassistente para gerar todos os SPs, Fns e Triggers em um único arquivo .sql.

insira a descrição da imagem aqui

Certifique-se de selecionar gatilhos também!

insira a descrição da imagem aqui

Em seguida, basta usar o Sublime ou o Bloco de notas para procurar a string que você precisa encontrar. Eu sei que isso pode ser uma abordagem bastante ineficiente e paranóica, mas funciona :)


12

Você também pode usar este:

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

9
-1 A desvantagem em comparação com outras opções INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITIONcontém apenas os primeiros 4000 caracteres da rotina.
Shannon Severance

8

Isso pode ajudá-lo!

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

Também você pode usar:

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

Isso inclui comentários


3
Você não deve usar syscomments para essa finalidade. O campo de texto é cortado em 4000 caracteres. O campo de definição de sys.sql_modules parece armazenar o texto inteiro (mais de 4000 de qualquer maneira)
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 do objeto (Exibir, Procedimento de armazenamento, Função escalar, Nome da função de tabela)

id (int) = número de identificação do objeto

xtype char (2) Tipo de objeto. Pode ser um dos seguintes tipos de objeto:

FN = função escalar

P = procedimento armazenado

V = Visualizar

TF = função de tabela


4

Criei um procedimento para pesquisar texto em procedimentos / funções, tabelas, visualizações ou trabalhos. O primeiro parâmetro @search é o critério de pesquisa, @ segmenta o destino da pesquisa, ou seja, procedimentos, tabelas etc. Se não especificado, pesquise em todas. @db é especificar o banco de dados a ser pesquisado, o padrão é o banco de dados atual. Aqui está minha consulta no SQL dinâmico.

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

Atualização: se você renomeou um procedimento, ele somente atualiza, sysobjectsmas não syscommentsmantém, o que mantém o nome antigo e, portanto, esse procedimento não será incluído no resultado da pesquisa, a menos que você solte e recrie o procedimento.


Siga este link para pesquisar o nome da coluna.
Weihui Guo 31/10

3

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

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

Usar esse duplo [[]ABD]é semelhante a escapar:

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

3

tente também o seguinte:

   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

Essa consulta é um texto de pesquisa no procedimento armazenado de todos os bancos de dados.

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

De vez em quando eu uso esse script para descobrir quais procs modificar, ou para descobrir o que usa uma coluna de uma tabela, ou essa tabela para remover algum lixo antigo. Ele verifica cada banco de dados na instância em que é executado pelo sp_msforeachdb maravilhosamente fornecido.

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 

ah, sim ... é isso mesmo!
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

Você também pode usar

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

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

END

e depois corra

exec [Search] 'text'

A cláusula WHERE está faltando uma referência de campo. Você também deve fazer referência o esquema (sys)
Roger Willcocks
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.