Làm cách nào để tìm một văn bản bên trong các thủ tục / trình kích hoạt SQL Server?


173

Tôi có một máy chủ liên kết sẽ thay đổi. Một số thủ tục gọi máy chủ được liên kết như thế này : [10.10.100.50].dbo.SPROCEDURE_EXAMPLE. Chúng tôi có các tác nhân cũng làm loại công việc này. Chúng ta cần tìm tất cả những nơi sử dụng [10.10.100.50]để thay đổi nó.

Trong SQL Server Management Studio Express, tôi đã không tìm thấy một tính năng như "tìm trong toàn bộ cơ sở dữ liệu" trong Visual Studio. Một sys-select đặc biệt có thể giúp tôi tìm thấy những gì tôi cần không?

Câu trả lời:


310

đây là một phần của quy trình tôi sử dụng trên hệ thống của mình để tìm văn bản ....

DECLARE @Search varchar(255)
SET @Search='[10.10.100.50]'

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 '%'+@Search+'%'
    ORDER BY 2,1

1
Ngoài ra, bạn có thể thêm phần này vào tập kết quả của mình để nhanh chóng xem văn bản chứa giá trị bạn đang tìm kiếm. , chuỗi con (m.def định, charindex (@Search, m.def định), 100)
Chris Rodriguez

2
@ChrisRodriguez, ý kiến ​​hay, nhưng hãy nhớ rằng đó sẽ chỉ là trận đấu đầu tiên có thể có nhiều người trong mỗi thủ tục / trình kích hoạt / chức năng
KM.

Không hợp lệ cho ràng buộc ( type = 'C')?
Kiquenet

18

Bạn có thể tìm thấy nó như

SELECT DISTINCT OBJECT_NAME(id) FROM syscomments WHERE [text] LIKE '%User%'

Nó sẽ liệt kê các tên thủ tục được lưu trữ riêng biệt có chứa văn bản như 'Người dùng' bên trong thủ tục được lưu trữ. Thêm thông tin


8
Chỉ cần lưu ý rằng syscommentsbảng lưu trữ các giá trị trong các khối 8000 ký tự, vì vậy nếu bạn không may có văn bản bạn đang tìm cách phân tách qua một trong các ranh giới này, bạn sẽ không tìm thấy nó bằng phương pháp này.
ErikE

17

[Trả lời muộn nhưng hy vọng hữu ích]

Sử dụng bảng hệ thống không phải lúc nào cũng cho kết quả chính xác 100% vì có thể có một số quy trình và / hoặc chế độ xem được lưu trữ được mã hóa trong trường hợp bạn sẽ cần sử dụng DAC kết nối để lấy dữ liệu bạn cần.

Tôi khuyên bạn nên sử dụng công cụ của bên thứ ba, chẳng hạn như Tìm kiếm ApexSQL để có thể xử lý các đối tượng được mã hóa một cách dễ dàng.

Bảng hệ thống Syscomments sẽ cung cấp giá trị null cho cột văn bản trong trường hợp đối tượng được mã hóa.


11
-- Declare the text we want to search for
DECLARE @Text nvarchar(4000);
SET @Text = 'employee';

-- Get the schema name, table name, and table type for:

-- Table names
SELECT
       TABLE_SCHEMA  AS 'Object Schema'
      ,TABLE_NAME    AS 'Object Name'
      ,TABLE_TYPE    AS 'Object Type'
      ,'Table Name'  AS 'TEXT Location'
FROM  INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%'+@Text+'%'
UNION
 --Column names
SELECT
      TABLE_SCHEMA   AS 'Object Schema'
      ,COLUMN_NAME   AS 'Object Name'
      ,'COLUMN'      AS 'Object Type'
      ,'Column Name' AS 'TEXT Location'
FROM  INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%'+@Text+'%'
UNION
-- Function or procedure bodies
SELECT
      SPECIFIC_SCHEMA     AS 'Object Schema'
      ,ROUTINE_NAME       AS 'Object Name'
      ,ROUTINE_TYPE       AS 'Object Type'
      ,ROUTINE_DEFINITION AS 'TEXT Location'
FROM  INFORMATION_SCHEMA.ROUTINES 
WHERE ROUTINE_DEFINITION LIKE '%'+@Text+'%'
      AND (ROUTINE_TYPE = 'function' OR ROUTINE_TYPE = 'procedure');

1
Điều này không bao gồm các kích hoạt như câu hỏi được hỏi
Enkode

Hợp lệ cho lượt xem, thủ tục lưu trữ, bảng do người dùng xác định ? và cho các kích hoạt, chức năng, ràng buộc, quy tắc, mặc định ?
Kiquenet

5

Điều này sẽ làm việc cho bạn:

use [ANALYTICS]  ---> put your DB name here
GO
SELECT sm.object_id, OBJECT_NAME(sm.object_id) AS object_name, o.type, o.type_desc, sm.definition
FROM sys.sql_modules AS sm
JOIN sys.objects AS o ON sm.object_id = o.object_id
where sm.definition like '%SEARCH_WORD_HERE%' collate SQL_Latin1_General_CP1_CI_AS
ORDER BY o.type;
GO

Không hợp lệ cho ràng buộc ( type = 'C')?
Kiquenet

4

nhiều giải pháp tốt hơn nhiều so với sửa đổi văn bản của các thủ tục, chức năng và chế độ xem được lưu trữ của bạn mỗi khi máy chủ được liên kết thay đổi. Dưới đây là một số tùy chọn:

  1. Cập nhật máy chủ được liên kết. Thay vì sử dụng một máy chủ liên kết tên với địa chỉ IP của nó, tạo ra một máy chủ liên kết mới với tên của các tài nguyên như Financehoặc DataLinkProdhoặc một số ví dụ. Sau đó, khi bạn cần thay đổi máy chủ nào đạt được, hãy cập nhật máy chủ được liên kết để trỏ đến máy chủ mới (hoặc thả nó và tạo lại nó).

  2. Mặc dù không may, bạn không thể tạo từ đồng nghĩa cho máy chủ hoặc lược đồ được liên kết, bạn CÓ THỂ tạo từ đồng nghĩa cho các đối tượng nằm trên máy chủ được liên kết. Ví dụ, thủ tục của bạn [10.10.100.50].dbo.SPROCEDURE_EXAMPLEcó thể bằng bí danh. Có lẽ tạo ra một lược đồ datalinkprod, sau đó CREATE SYNONYM datalinkprod.dbo_SPROCEDURE_EXAMPLE FOR [10.10.100.50].dbo.SPROCEDURE_EXAMPLE;. Sau đó, viết một thủ tục được lưu trữ chấp nhận tên máy chủ được liên kết, truy vấn tất cả các đối tượng tiềm năng từ cơ sở dữ liệu từ xa và (re) tạo từ đồng nghĩa cho chúng. Tất cả các SP và chức năng của bạn được viết lại chỉ một lần để sử dụng tên đồng nghĩa bắt đầu datalinkprodvà sau đó, để thay đổi từ một máy chủ được liên kết này sang một máy chủ khác mà bạn vừa làm EXEC dbo.SwitchLinkedServer '[10.10.100.51]';và trong một phần giây bạn đang sử dụng một máy chủ được liên kết khác.

Có thể có nhiều lựa chọn hơn nữa. Tôi đặc biệt khuyên bạn nên sử dụng các kỹ thuật ưu việt của tiền xử lý, cấu hình hoặc xác định thay vì thay đổi các tập lệnh do con người viết. Tự động cập nhật các tập lệnh do máy tạo ra là ổn, đây là tiền xử lý. Làm mọi thứ bằng tay là khủng khiếp.


Tôi đồng ý với đề nghị của bạn. Nhưng trong tình huống như những gì OP mô tả, bạn vẫn cần tìm tất cả các thủ tục được lưu trữ có chứa IP máy chủ. Và ngay cả khi bạn chỉ phải làm một lần, làm bằng tay có thể là rất nhiều công việc.
Paul Groke

@PaulGroke Vâng, công việc "rất nhiều" này là khoản nợ kỹ thuật gây ra bởi các lựa chọn kỹ thuật kém trong hệ thống cố thủ. Phải mất thời gian để thu hồi từ khoản tiền này trả hết khoản nợ tích lũy. Nhưng đề nghị của tôi là làm thế nào để xây dựng sự giàu có về kỹ thuật, bây giờ hãy dành nhiều thời gian hơn để nhanh hơn, nhanh nhẹn hơn và đáng tin cậy hơn sau này. Đọc bài viết Big Ball of Mud cho một số ý tưởng xung quanh này.
ErikE

Ý tôi là: Điều gì sai khi giảm "trả nợ" hoạt động bằng cách sử dụng một trong những tuyên bố CHỌN mà người khác đăng ở đây?
Paul Groke

@PaulGroke Không có gì sai với cách nhanh chóng để tìm các đối tượng có thể tham chiếu đến máy chủ được liên kết. Nhưng bạn có biết rằng câu ngạn ngữ cũ về "dạy một người đàn ông câu cá" hơn là "cho một người đàn ông một con cá"? Vâng. Điều đó
ErikE

@ErikE Điều là - bạn không dạy anh ta cách câu cá, chỉ cần nói rằng nếu anh ta câu cá, anh ta có thể lấy thức ăn. Câu trả lời của bạn là lời khuyên tuyệt vời, nhưng không giúp OP thực sự thực hiện nó. Thêm một cách tìm các tài liệu tham khảo đó để bạn có thể thay thế chúng bằng một cái gì đó được thiết kế tốt hơn sẽ làm cho câu trả lời này tốt hơn.
T. Sar

2
select text
from syscomments
where text like '%your text here%'

2

Cái này tôi đã thử trong SQL2008, có thể tìm kiếm từ tất cả các db một lần.

Create table #temp1 
(ServerName varchar(64), dbname varchar(64)
,spName varchar(128),ObjectType varchar(32), SearchString varchar(64))

Declare @dbid smallint, @dbname varchar(64), @longstr varchar(5000)
Declare @searhString VARCHAR(250)

set  @searhString='firstweek'

declare db_cursor cursor for 
select dbid, [name] 
from master..sysdatabases
where [name] not in ('master', 'model', 'msdb', 'tempdb', 'northwind', 'pubs')



open db_cursor
fetch next from db_cursor into @dbid, @dbname

while (@@fetch_status = 0)
begin
    PRINT 'DB='+@dbname
    set @longstr = 'Use ' + @dbname + char(13) +        
        'insert into #temp1 ' + char(13) +  
        'SELECT @@ServerName,  ''' + @dbname + ''', Name 
        , case  when [Type]= ''P'' Then ''Procedure''
                when[Type]= ''V'' Then ''View''
                when [Type]=  ''TF'' Then ''Table-Valued Function'' 
                when [Type]=  ''FN'' Then ''Function'' 
                when [Type]=  ''TR'' Then ''Trigger'' 
                else [Type]/*''Others''*/
                end 
        , '''+ @searhString +''' FROM  [SYS].[SYSCOMMEnTS]
        JOIN  [SYS].objects ON ID = object_id
        WHERE TEXT LIKE ''%' + @searhString + '%'''

 exec (@longstr)
 fetch next from db_cursor into @dbid, @dbname
end

close db_cursor
deallocate db_cursor
select * from #temp1
Drop table #temp1

0

Tôi sử dụng cái này cho công việc. rời khỏi [] mặc dù trong trường @TEXT, dường như muốn trả lại mọi thứ ...

THIẾT LẬP NOCOUNT

KHAI THÁC @ TEXT VARCHAR (250)
KHAI THÁC @Query VARCHAR (250)

CHỌN @ TEXT = '10 .10.100.50 '

CREATE TABLE #results (db VARCHAR (64), tên đối tượng VARCHAR (100), xtype VARCHAR (10), định nghĩa văn bản)

CHỌN @TEXT dưới dạng 'Chuỗi tìm kiếm'
KHAI THÁC #database HIỆN TẠI CHO TÊN CHỌN TỪ chủ..sysdatabase trong đó dbid> 4
    KHAI THÁC @c_dbname varchar (64)   
    MỞ #database
    FETCH #database INTO @c_dbname   
    WHILE @@ FETCH_STATUS -1
    BẮT ĐẦU
        CHỌN @Query = 'XÁC NHẬN VÀO #results'
        CHỌN @Query = @Query + 'CHỌN' '' + @c_dbname + '' 'AS db, o.name, o.xtype, m.def định'   
        CHỌN @Query = @Query + 'TỪ'+@c_dbname+'.sys.sql_modules m'   
        CHỌN @SQL = @SQL + 'INNER THAM GIA' + @ c_dbname + '.. sysobjects o ON m.object_id = o.id'   
        CHỌN @Query = @Query + 'WHERE [định nghĩa] THÍCH' '%' + @ TEXT + '%' ''   
        EXEC (@Query)
        FETCH #database INTO @c_dbname
    KẾT THÚC
    ĐÓNG # cơ sở dữ liệu
DEALLOCATE #database

CHỌN * TỪ #results thứ tự theo db, xtype, tên đối tượng
BẢNG DROP #results

0

Tôi đã sử dụng những thứ này trong quá khứ:

Trong trường hợp cụ thể này, khi bạn cần thay thế một chuỗi cụ thể qua các thủ tục được lưu trữ, liên kết đầu tiên có lẽ phù hợp hơn.

Hơi lạc đề một chút, bổ trợ Tìm nhanh cũng hữu ích cho việc tìm kiếm tên đối tượng với SQL Server Management Studio. Có một phiên bản sửa đổi có sẵn với một số cải tiến và một phiên bản mới hơn cũng có sẵn trên Codeplex cùng với một số bổ trợ hữu ích khác.


0

Bất kỳ tìm kiếm nào với câu lệnh select đều mang lại cho bạn tên đối tượng, trong đó từ khóa tìm kiếm chứa. Cách dễ nhất và hiệu quả là lấy tập lệnh của thủ tục / hàm và sau đó tìm kiếm trong tệp văn bản được tạo, tôi cũng làm theo kỹ thuật này :) Vì vậy, bạn chính xác là chính xác.


0
SELECT ROUTINE_TYPE, ROUTINE_NAME, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES 
WHERE ROUTINE_DEFINITION LIKE '%Your Text%' 

0

Chỉ cần viết này cho chung ref đầy đủ bên ngoài ref

create table #XRefDBs(xtype varchar(2),SourceDB varchar(100), Object varchar(100), RefDB varchar(100))

declare @sourcedbname varchar(100),
        @searchfordbname varchar(100),
        @sql nvarchar(4000)
declare curs cursor for
    select name 
    from sysdatabases
    where dbid>4
open curs
fetch next from curs into @sourcedbname
while @@fetch_status=0
    begin
    print @sourcedbname
    declare curs2 cursor for 
        select name 
        from sysdatabases
        where dbid>4
        and name <> @sourcedbname
    open curs2
    fetch next from curs2 into @searchfordbname
    while @@fetch_status=0
        begin
        print @searchfordbname
        set @sql = 
        'INSERT INTO #XRefDBs (xtype,SourceDB,Object, RefDB)
        select DISTINCT o.xtype,'''+@sourcedbname+''', o.name,'''+@searchfordbname+'''
        from '+@sourcedbname+'.dbo.syscomments c
        join '+@sourcedbname+'.dbo.sysobjects o on c.id=o.id
        where o.xtype in (''V'',''P'',''FN'',''TR'')
        and (text like ''%'+@searchfordbname+'.%''
          or text like ''%'+@searchfordbname+'].%'')'
        print @sql
        exec sp_executesql @sql
        fetch next from curs2 into @searchfordbname
        end
    close curs2
    deallocate curs2
    fetch next from curs into @sourcedbname
    end
close curs
deallocate curs

select * from #XRefDBs

-1

Bạn có thể tìm kiếm trong các định nghĩa của tất cả các đối tượng cơ sở dữ liệu bằng cách sử dụng SQL sau:

SELECT 
    o.name, 
    o.id, 
    c.text,
    o.type
FROM 
    sysobjects o 
RIGHT JOIN syscomments c 
    ON o.id = c.id 
WHERE 
    c.text like '%text_to_find%'
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.