Buscar texto en procedimiento almacenado en SQL Server

820

Quiero buscar un texto de todos los procedimientos almacenados de mi base de datos. Yo uso el siguiente 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]%';

Quiero buscar [ABD]en todos los procedimientos almacenados, incluidos los corchetes, pero no está dando el resultado adecuado. ¿Cómo puedo cambiar mi consulta para lograr esto?

DharaPPatel
fuente

Respuestas:

570

Escapar de los corchetes:

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

Luego, los corchetes se tratarán como literales de cadena, no como comodines.

Mahmoud Gamal
fuente
no dé el nombre del esquema :(
Imad
44
@Imad Puede obtener el nombre del esquema agregando SCHEMA_NAME(o.schema_id) AS Schema_Namea la cláusula select.
patricus
66
Esto no funciona con procedimientos almacenados más largos. Utilice el SQL de Ullas a continuación en su lugar.
Charles Graham
3
Descubrí por las malas que esta respuesta solo buscará los primeros 4000 caracteres del texto del procedimiento almacenado. Mira este enlace para ver la respuesta real. sqlhints.com/2011/10/01/…
Hunter Nelson
Lo mismo aquí, información_esquema no buscó contenido-texto (dentro de SProcs), en cambio el uso de "sys.procedures" funcionó para mí. Entiendo que Microsoft recomienda el uso de información_esquema, sin embargo, aparentemente esto no está funcionando para muchos, por lo tanto, Microsoft debería investigar este problema.
Eddie Kumar
319

Prueba esta solicitud:

Consulta

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

¿Has intentado usar algunas de las herramientas de terceros para hacer la búsqueda? Hay varios disponibles que son gratuitos y que me ahorraron un montón de tiempo en el pasado.

A continuación hay dos complementos de SSMS que utilicé con buen éxito.

Búsqueda de ApexSQL: busca tanto esquemas como datos en bases de datos y tiene características adicionales como el seguimiento de dependencias y más ...

Paquete de herramientas de SSMS : tiene la misma funcionalidad de búsqueda que la anterior y otras características interesantes. No es gratuito para SQL Server 2012, pero sigue siendo muy asequible.

Sé que esta respuesta no está 100% relacionada con las preguntas (que era más específica), pero espero que otros la encuentren útil.

David Smithers
fuente
35

Normalmente ejecuto lo siguiente para lograr eso:

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

Buena práctica para trabajar con SQL Server.

Cree el procedimiento almacenado a continuación y configure la tecla breve,

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

Ahora: configure la tecla corta como se muestra a continuación,

ingrese la descripción de la imagen aquí

La próxima vez que cada vez que desee encontrar un texto en particular en cualquiera de los cuatro objetos, como Store procedure, Views, Functionsy Tables. Solo necesita escribir esa palabra clave y presionar la tecla de acceso directo.

Por ejemplo: deseo buscar 'PaymentTable' y luego escribir 'PaymentTable' y asegurarme de seleccionar o resaltar la palabra clave escrita en el editor de consultas y presionar la tecla de acceso directo ctrl+4: le proporcionará el resultado completo.

pedram
fuente
En SSMS v18.2 (conectado a Azure) el código funciona muy bien. La tecla corta devuelve ¿ Procedure or function 'Searchinall' expects parameter '@strFind', which was not suppliedAlguna idea?
gordon613
@ gordon613 ¿ha escrito palabras clave para buscar mientras presiona la tecla de acceso directo en SSMS? por ejemplo, 'Empleado' y luego ctrl + 4
pedram
@ pedram.- gracias! Ahora lo tengo funcionando: en mi configuración, debe escribir la palabra clave, luego resaltarla y luego presionar CTRL + 4
gordon613
Sí, debemos resaltar / seleccionar la palabra clave antes de presionar CTRL + 4. ¡Gracias amigo!
Pedram 01 de
1
@AngelWarrior, es posible que lo hayas probado en una nueva consulta y debería haber funcionado para ti. Me refiero a que no es necesario reiniciar el SSMS. Gracias por proporcionar la ruta de acceso directo para SSMS 18.2.
pedram
19

Tome esto como una alternativa "sucia", pero esto me salvó muchas veces, especialmente cuando no estaba familiarizado con el proyecto DB. A veces intenta buscar una cadena dentro de todos los SP y olvida que parte de la lógica relacionada puede haberse ocultado entre Funciones y Disparadores o simplemente puede estar redactada de manera diferente de lo que pensaba.

Desde su MSSMS puede hacer clic derecho en su base de datos y seleccionar el Tasks -> Generate Scriptsasistente para generar todos los SP, Fns y disparadores en un solo archivo .sql.

ingrese la descripción de la imagen aquí

¡Asegúrate de seleccionar Triggers también!

ingrese la descripción de la imagen aquí

Luego use Sublime o Notepad para buscar la cadena que necesita encontrar. Sé que esto puede ser un enfoque bastante ineficiente y paranoico, pero funciona :)

Milán
fuente
12

También puedes usar este:

SELECT * 
FROM INFORMATION_SCHEMA.ROUTINES 
WHERE ROUTINE_DEFINITION like '%Search_String%'
usuario2846553
fuente
99
-1 La desventaja en comparación con otras opciones INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITIONsolo contiene los primeros 4000 caracteres de la rutina.
Shannon Severance
8

¡Te puede ayudar!

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
Anil Singh
fuente
7
select top 10 * from
sys.procedures
where object_definition(object_id) like '%\[ABD\]%'
usuario1001101
fuente
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]%';
GRAMO
fuente
5

También puedes usar:

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

Eso incluye comentarios

Daniel RG
fuente
3
No debe usar syscomments para este propósito. El campo de texto se corta en 4000 caracteres. El campo de definición de sys.sql_modules parece almacenar todo el texto (más de 4000 de todos modos)
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]) -> Nombre del objeto (Ver, Procedimiento de almacenamiento, Función escalar, Nombre de función de tabla)

id (int) = número de identificación del objeto

xtype char (2) Tipo de objeto. Puede ser uno de los siguientes tipos de objeto:

FN = función escalar

P = procedimiento almacenado

V = Ver

TF = función de tabla

Atahan Ceylan
fuente
4

Creé un procedimiento para buscar texto en procedimientos / funciones, tablas, vistas o trabajos. El primer parámetro @search es el criterio de búsqueda, @target el objetivo de búsqueda, es decir, procedimientos, tablas, etc. Si no se especifica, busque todos. @db es para especificar la base de datos a buscar, predeterminada para su base de datos actual. Aquí está mi consulta en 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

Actualización: si cambió el nombre de un procedimiento, solo se actualiza sysobjectspero no syscomments, lo que mantiene el nombre anterior y, por lo tanto, ese procedimiento no se incluirá en el resultado de la búsqueda a menos que lo descarte y lo vuelva a crear.

Weihui Guo
fuente
Siga este enlace para buscar el nombre de la columna.
Weihui Guo
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 este doble [[]ABD]es similar a escapar:

WHERE m.definition LIKE '%[[]ABD]%'
bonCodigo
fuente
3

prueba también esto:

   SELECT ROUTINE_NAME 
    FROM INFORMATION_SCHEMA.ROUTINES 
    WHERE ROUTINE_DEFINITION like '%\[ABD\]%'
ANUNCIO
fuente
1
Select distinct OBJECT_NAME(id) from syscomments where text like '%string%' AND OBJECTPROPERTY(id, 'IsProcedure') = 1 
Gopakumar N.Kurup
fuente
1

Esta consulta es texto de búsqueda en procedimiento almacenado de todas las bases de datos.

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
Nokcha
fuente
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')
groggyjava
fuente
0

De vez en cuando utilizo este script para descubrir qué procesos modificar, o para averiguar qué usa una columna de una tabla, o esa tabla para eliminar algo de basura vieja. Comprueba cada base de datos en la instancia en la que se ejecuta sp_msforeachdb maravillosamente suministrado.

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 
jesterm
fuente
oh, ya ... es así!
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
Abhinav Sharma
fuente
-2

También puedes usar

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

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

END

y luego correr

exec [Search] 'text'
Kamruzzaman
fuente
A la cláusula WHERE le falta una referencia de campo. También debe hacer referencia al esquema (sys)
Roger Willcocks