SQL Server yordamları / tetikleyicileri içinde bir metin nasıl bulunur?


173

Değişecek bağlı bir sunucum var. Bazı prosedürler böyle bağlantılı sunucu diyoruz: [10.10.100.50].dbo.SPROCEDURE_EXAMPLE. Bu tür işleri de yapan tetikleyicilerimiz var. Kullanan tüm yerleri bulmalıyız[10.10.100.50]Değiştirmek için gerekiyor.

SQL Server Management Studio Express'te, Visual Studio'da "tüm veritabanında bul" gibi bir özellik bulamadım. Özel bir sys-select ihtiyacım olanı bulmama yardımcı olabilir mi?

Yanıtlar:


310

İşte metin bulmak için benim sistemde kullandığım bir prosedür kısmı ...

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
Ayrıca, aradığınız değeri içeren metni hızlı bir şekilde görmek için bunu sonuç kümenize ekleyebilirsiniz. , alt dize (m.definition, charindex (@Search, m.definition), 100)
Chris Rodriguez

2
@ChrisRodriguez, iyi fikir, ancak her prosedür / tetikleyici / fonksiyon
KM'de

Kısıtlamalar ( type = 'C') için geçerli değil mi?
Kiquenet

18

Gibi bulabilirsiniz

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

Saklı yordamın içinde 'Kullanıcı' gibi metin içeren ayrı saklı yordam adlarını listeler. Daha fazla bilgi


8
Sadece unutmayın syscommentsbu sınırların karşılaşmanız an için metin sen arama şanssız yeterli eğer öyleyse masa depolar 8000 karakterlik parçalar halinde değerleri, bu yöntemle bulamaz.
ErikE

17

[Geç cevap ama umarım faydalıdır]

Sistem tablolarını kullanmak her zaman% 100 doğru sonuç vermez, çünkü bazı saklı yordamların ve / veya görünümlerin şifrelenmesi olasılığı olabilir, bu durumda ihtiyacınız olan verileri almak için DAC bağlantısını kullanmanız gerekir.

Şifrelenmiş nesnelerle kolayca başa çıkabilen ApexSQL Arama gibi bir üçüncü taraf aracı kullanmanızı tavsiye ederim .

Syscomments sistem tablosu, nesnenin şifrelenmesi durumunda metin sütunu için boş değer verecektir.


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
Bu, sorulan soru gibi tetikleyicileri içermez
Enkode

Geçerli için görünümler, saklı yordamlar, kullanıcı tabloları tanımlı ? ve tetikleyiciler, işlevler, Kısıtlamalar, Kurallar, Varsayılanlar için ?
Kiquenet

5

Bu sizin için çalışacaktır:

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

Kısıtlamalar ( type = 'C') için geçerli değil mi?
Kiquenet

4

Bağlı sunucu her değiştiğinde, saklı yordamlarınızın, işlevlerinizin ve görünümlerin metnini değiştirmekten çok daha iyi çözümler vardır . İşte bazı seçenekler:

  1. Bağlı sunucuyu güncelleyin. IP adresiyle adlandırılmış bağlantılı bir sunucu kullanmak yerine, kaynak adı Financeveya benzeri bir adla yeni bir bağlantılı sunucu oluşturun DataLinkProd. Ardından, hangi sunucuya ulaşıldığını değiştirmeniz gerektiğinde, bağlı sunucuyu yeni sunucuyu gösterecek şekilde güncelleyin (veya bırakın ve yeniden oluşturun).

  2. Ne yazık ki bağlı sunucular veya şemalar için eşanlamlılar oluşturamazken, bağlı sunucularda bulunan nesneler için eş anlamlılar oluşturabilirsiniz. Örneğin, işleminiz diğer [10.10.100.50].dbo.SPROCEDURE_EXAMPLEadlarla yapılabilir. Belki bir şema oluşturmak datalinkprod, sonra CREATE SYNONYM datalinkprod.dbo_SPROCEDURE_EXAMPLE FOR [10.10.100.50].dbo.SPROCEDURE_EXAMPLE;. Ardından, uzak veritabanındaki tüm potansiyel nesneleri sorgulayan ve (yeniden) onlar için eşanlamlılar oluşturan bağlantılı bir sunucu adını kabul eden saklı bir yordam yazın. Tüm SP'leriniz ve işlevleriniz yalnızca bir kez yeniden adlandırılır datalinkprodve bundan sonra eşanlamlı adları kullanmak için bir kez yeniden yazılır ve yaptığınız bir bağlantılı sunucudan diğerine geçmek için sadece EXEC dbo.SwitchLinkedServer '[10.10.100.51]';bir saniye içinde farklı bir bağlantılı sunucu kullanıyorsunuz.

Daha fazla seçenek olabilir. İnsan tarafından yazılmış komut dosyalarını değiştirmek yerine üstün ön işleme, yapılandırma veya dolaylı tekniklerin kullanılmasını önemle tavsiye ederim. Makine tarafından oluşturulan komut dosyalarını otomatik olarak güncellemek iyidir, bu önişlemdir. Bir şeyleri manuel olarak yapmak korkunç.


Önerinize katılıyorum. Ancak OP'nin açıkladığı gibi bir durumda, hala sunucu IP'sini içeren tüm saklı yordamları bulmanız gerekir. Ve sadece bir kez yapmak zorunda olsanız bile, elle yapmak çok iş olabilir.
Paul GROKE

@PaulGroke Evet, bu "çok" iş, yerleşik sistemdeki zayıf teknik tercihlerin neden olduğu teknik borçtur. Bundan kurtulmak zaman alır - tahakkuk eden borcun ödenmesi. Ancak benim önerim teknik zenginliğin nasıl oluşturulacağı - daha sonra daha hızlı, daha çevik ve daha güvenilir olmak için daha fazla zaman harcamak. Bu konuda bazı fikirler için Big Ball of Mud makalesini okuyun .
ErikE

Demek istediğim şuydu: Başkalarının buraya gönderdiği SELECT ifadelerinden birini kullanarak "borcunu ödemek" işini azaltarak yanlış olan nedir?
Paul Groke

@PaulGroke Bağlantılı sunucuya başvurabilecek nesneleri bulmanın hızlı bir yolunda yanlış bir şey yoktur. Ama biliyorsunuz ki "adama balık vermek" yerine "bir erkeği balık tutmayı öğretin". Evet. Bu şey.
ErikE

@ErikE Şey - ona balık tutmayı öğretmiyorsunuz, sadece balık tutarsa ​​yiyecek alabileceğini söylüyor. Cevabınız harika bir tavsiye, ancak OP'nin bunu gerçekten uygulamasına yardımcı olmuyor. Daha iyi tasarlanmış bir şeyle değiştirebilmeniz için bu referansları bulmanın bir yolunu eklemek, bu yanıtı daha iyi hale getirecektir.
T. Sar

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

2

Bu bir seferde tüm db arama yapabilirsiniz SQL2008, çalıştı.

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

Bunu iş için kullanıyorum. @TEXT alanında [] 'ı bırak, her şeyi geri döndürmek istiyor gibi görünüyor ...

NOCOUNT'u AÇIN

DECLARE @TEXT VARCHAR (250)
DECLARE @SQL VARCHAR (250)

@ METİN SEÇ = '10 .10.100.50 '

CREATE TABLE #results (db VARCHAR (64), nesne adı VARCHAR (100), xtype VARCHAR (10), tanım TEXT)

@TEXT 'Arama Dizesi' olarak SEÇ
DECLARE #databases master ..sysdatabases dan dBid> 4
    DECLARE @c_dbname varchar (64)   
    OPEN #databases
    FETCH #databases INTO @c_dbname   
    @ @ FETCH_STATUS -1
    BAŞLA
        SELECT @SQL = '#results'a EKLE'
        SELECT @SQL = @SQL + 'SELECT' '' + @c_dbname + '' 'AS db, o.name, o.xtype, m.definition'   
        @SQL = @SQL + 'FROM'+@c_dbname+'.sys.sql_modules m'yi SEÇİN   
        SELECT @SQL = @SQL + 'INNER JOIN' + @ c_dbname + '.. sysobjects o ON m.object_id = o.id'   
        @SQL = @SQL + 'NEREDE [tanım] GİBİ' '%' + @ METİN + '%' ''   
        EXEC (@SQL)
        FETCH #databases INTO @c_dbname
    SON
    KAPAT # veritabanları
DEALLOCATE #databases

SELECT * FROM #dults, xtype, objectname ile #results sıralaması
DROP TABLE #results

0

Bunları geçmişte kullandım:

Saklı yordamlar arasında belirli bir dizeyi değiştirmeniz gerektiğinde bu özel durumda, ilk bağlantı muhtemelen daha önemlidir.

Biraz konu dışı olan Hızlı Bul eklentisi , SQL Server Management Studio ile nesne adlarını aramak için de yararlıdır. Bir var modifiye versiyonu bazı iyileştirmeler ile kullanılabilir ve başka yeni bir sürümü de bazı diğer yararlı eklentilerle Codeplex geçerli de.


0

Select deyimiyle yapılan herhangi bir arama, yalnızca arama anahtar kelimesinin bulunduğu nesne adını verir. En kolay ve verimli yolu prosedür / fonksiyon komut dosyası almak ve daha sonra oluşturulan metin dosyasında arama, ben de bu tekniği izler :) Yani tam bir kesin vardır.


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

0

Sadece genel tam dış çapraz ref için yazdı

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

Aşağıdaki SQL'i kullanarak tüm veritabanı nesnelerinin tanımları içinde arama yapabilirsiniz:

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%'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.