Tìm kiếm văn bản trong thủ tục được lưu trữ trong SQL Server


820

Tôi muốn tìm kiếm một văn bản từ tất cả các thủ tục lưu trữ cơ sở dữ liệu của tôi. Tôi sử dụng SQL dưới đây:

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

Tôi muốn tìm kiếm [ABD]trong tất cả các quy trình được lưu trữ, kể cả dấu ngoặc vuông, nhưng nó không cho kết quả chính xác. Làm thế nào tôi có thể thay đổi truy vấn của mình để đạt được điều này?

Câu trả lời:


570

Thoát khỏi dấu ngoặc vuông:

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

Sau đó, dấu ngoặc vuông sẽ được coi là một chuỗi ký tự không phải là thẻ hoang dã.


không đặt tên lược đồ :(
Imad

4
@Imad Bạn có thể lấy tên lược đồ bằng cách thêm SCHEMA_NAME(o.schema_id) AS Schema_Namevào mệnh đề select.
patricus

6
Điều này không làm việc với các thủ tục lưu trữ lâu hơn. Sử dụng SQL của Ullas bên dưới thay thế.
Charles Graham

3
Tôi phát hiện ra một cách khó khăn là câu trả lời này sẽ chỉ tìm kiếm 4000 ký tự đầu tiên của văn bản thủ tục được lưu trữ. Kiểm tra liên kết này cho câu trả lời thực sự. sqlhint.com/2011/10/01/ từ
Hunter Nelson

Tương tự ở đây, information_schema đã không tìm kiếm nội dung văn bản (trong SProcs), thay vào đó sử dụng "sys.procedures" làm việc cho tôi. Tôi hiểu rằng Microsoft khuyến nghị sử dụng information_schema, tuy nhiên rõ ràng điều này không hiệu quả với nhiều người, do đó Microsoft nên xem xét vấn đề này.
Eddie Kumar

319

Hãy thử yêu cầu này:

Truy vấn

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

56

Bạn đã thử sử dụng một số công cụ của bên thứ ba để thực hiện tìm kiếm chưa? Có một số có sẵn ngoài đó là miễn phí và điều đó giúp tôi tiết kiệm rất nhiều thời gian trong quá khứ.

Dưới đây là hai Addins SSMS tôi đã sử dụng rất thành công.

ApexQuery Search - Tìm kiếm cả lược đồ và dữ liệu trong cơ sở dữ liệu và có các tính năng bổ sung như theo dõi phụ thuộc và nhiều hơn nữa

Gói công cụ SSMS - Có chức năng tìm kiếm tương tự như trước đây và một số tính năng thú vị khác. Không miễn phí cho SQL Server 2012 nhưng vẫn rất phải chăng.

Tôi biết câu trả lời này không liên quan 100% đến các câu hỏi (cụ thể hơn) nhưng hy vọng những người khác sẽ thấy điều này hữu ích.


35

Tôi thường chạy như sau để đạt được điều đó:

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

31

Thực hành tốt để làm việc với SQL Server.

Tạo thủ tục được lưu trữ bên dưới và đặt khóa ngắn,

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

Bây giờ - Đặt phím ngắn như bên dưới,

nhập mô tả hình ảnh ở đây

Vì vậy, thời gian tiếp theo bất cứ khi nào bạn muốn tìm một văn bản đặc biệt trong bất kỳ trong bốn đối tượng như Store procedure, Views, FunctionsTables. Bạn chỉ cần viết từ khóa đó và nhấn phím tắt.

Ví dụ: Tôi muốn tìm kiếm 'PaymentTable' sau đó viết 'PaymentTable' và đảm bảo bạn chọn hoặc tô sáng từ khóa bằng văn bản trong trình soạn thảo truy vấn và nhấn phím tắt ctrl+4- nó sẽ cung cấp cho bạn kết quả đầy đủ.


Trong SSMS v18.2 (được kết nối với Azure), mã hoạt động rất tốt. Phím ngắn trả về Procedure or function 'Searchinall' expects parameter '@strFind', which was not suppliedý tưởng nào?
gordon613

@ gordon613 bạn đã gõ từ khóa để tìm kiếm trong khi nhấn phím tắt trên SSMS? ví dụ: 'Nhân viên' và sau đó ctrl + 4
pedram

@ pedram.- cảm ơn! Bây giờ tôi đã làm cho nó hoạt động - trên thiết lập của tôi, bạn cần nhập từ khóa, sau đó tô sáng nó và sau đó nhấn CTRL + 4
gordon613

có, chúng tôi cần làm nổi bật / chọn từ khóa trước khi nhấn CTRL + 4. Cảm ơn bạn đời!
pedram

1
@AngelWar Warrior, Bạn có thể đã thử nó trong truy vấn mới và nó sẽ hoạt động cho bạn. Tôi có nghĩa là không cần phải khởi động lại SSMS. Cảm ơn bạn đã cung cấp đường dẫn Phím tắt cho SSMS 18.2.
bàn đạp


19

Vui lòng xem đây là một giải pháp thay thế "bẩn" nhưng điều này đã giúp tôi tiết kiệm được nhiều lần, đặc biệt khi tôi không quen với dự án DB. Đôi khi bạn đang cố gắng tìm kiếm một chuỗi trong tất cả các SP và quên rằng một số logic liên quan có thể đã bị ẩn giữa Hàm và Triggers hoặc nó có thể được diễn đạt đơn giản khác với bạn nghĩ.

Từ MSSMS của bạn, bạn có thể nhấp chuột phải vào DB của mình và chọn Tasks -> Generate Scriptstrình hướng dẫn để xuất tất cả các SP, Fns và Triggers thành một tệp .sql duy nhất.

nhập mô tả hình ảnh ở đây

Hãy chắc chắn để chọn Triggers quá!

nhập mô tả hình ảnh ở đây

Sau đó, chỉ cần sử dụng Sublime hoặc Notepad để tìm kiếm chuỗi bạn cần tìm. Tôi biết cách này có thể không hiệu quả và cách tiếp cận hoang tưởng nhưng nó hoạt động :)


12

Bạn cũng có thể sử dụng cái này:

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

9
-1 Nhược điểm so với các tùy chọn khác INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITIONchỉ giữ 4000 ký tự đầu tiên của thường trình.
Shannon Severance

8

Nó có thể giúp bạn!

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

Ngoài ra, bạn có thể sử dụng:

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

Đó là ý kiến


3
Bạn không nên sử dụng hệ thống cho mục đích này. Trường văn bản cắt ở 4000 ký tự. Trường định nghĩa từ sys.sql_modules dường như lưu trữ toàn bộ văn bản (dù sao cũng hơn 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%' ) 

OBarget_NAME ([id]) -> Tên đối tượng (Xem, Thủ tục lưu trữ, Hàm vô hướng, Tên hàm bảng)

id (int) = Số nhận dạng đối tượng

xtype char (2) Loại đối tượng. Có thể là một trong các loại đối tượng sau:

FN = Hàm vô hướng

P = Thủ tục lưu trữ

V = Xem

Hàm TF = Bảng


4

Tôi đã tạo một quy trình để tìm kiếm văn bản trong các thủ tục / chức năng, bảng, dạng xem hoặc công việc. Tham số đầu tiên @search là tiêu chí tìm kiếm, @target mục tiêu tìm kiếm, nghĩa là các thủ tục, bảng, v.v. Nếu không được chỉ định, hãy tìm kiếm tất cả. @db là chỉ định cơ sở dữ liệu để tìm kiếm, mặc định cho cơ sở dữ liệu hiện tại của bạn. Đây là truy vấn của tôi trong SQL động.

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

Cập nhật: Nếu bạn đổi tên một thủ tục, nó chỉ cập nhật sysobjectsnhưng không syscommentsgiữ lại tên cũ và do đó thủ tục đó sẽ không được đưa vào kết quả tìm kiếm trừ khi bạn bỏ và tạo lại thủ tục.


Theo liên kết này để tìm kiếm tên cột.
Quách Weihui

3

Sử dụng 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 ;

Sử dụng 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 ; 

Sử dụng gấp đôi [[]ABD]này tương tự như thoát:

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

3

cũng thử điều này:

   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

Truy vấn này là văn bản tìm kiếm trong thủ tục lưu trữ từ tất cả các cơ sở dữ liệu.

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

Mỗi lần tôi thường sử dụng tập lệnh này để tìm ra những procs nào cần sửa đổi, hoặc tìm ra cái gì sử dụng một cột của bảng hoặc bảng đó để loại bỏ một số rác cũ. Nó kiểm tra từng cơ sở dữ liệu trong trường hợp nó được chạy bởi 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, ya ... là như vậy!
Bitcoin giết người điên cuồng

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

Bạn cũng có thể dùng

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

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

END

và sau đó chạy

exec [Search] 'text'

Mệnh đề WHERE thiếu tham chiếu trường. Bạn cũng nên tham khảo lược đồ (sys)
Roger Willcocks
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.