web-dev-qa-db-ja.com

SQL Serverのプロシージャ/トリガー内のテキストを見つける方法は?

変更されるリンクサーバーがあります。一部のプロシージャは、[10.10.100.50].dbo.SPROCEDURE_EXAMPLEのようにリンクサーバーを呼び出します。この種の作業を行うトリガーもあります。変更するには、[10.10.100.50]を使用するすべての場所を見つける必要があります。

SQL Server Management Studio Expressで、Visual Studioの「データベース全体を検索」などの機能が見つかりませんでした。特別なsys-selectで必要なものを見つけることができますか?

165

これは、システムでテキストを検索するために使用する手順の一部です。

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
289
KM.

[遅い回答ですが、うまくいけば役に立つ]

一部のストアドプロシージャやビューが暗号化されている可能性があるため、システムテーブルを使用しても常に100%正しい結果が得られるとは限らないため、 DAC 必要なデータを取得するための接続。

暗号化されたオブジェクトを簡単に処理できる ApexSQL Search などのサードパーティツールを使用することをお勧めします。

Syscommentsシステムテーブルは、オブジェクトが暗号化されている場合にテキスト列にnull値を提供します。

17
Dwoolk

次のように見つけることができます

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

ストアドプロシージャ内に「ユーザー」などのテキストを含む個別のストアドプロシージャ名がリストされます。 詳細

16
ashish.chotalia
-- 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');
11
Heba Mahmoud

これはあなたのために働くでしょう:

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
5
laurens

リンクサーバーが変更されるたびにストアドプロシージャ、関数、およびビューのテキストを変更するよりも、muchより優れたソリューションがあります。以下にいくつかのオプションを示します。

  1. リンクサーバーを更新します。 IPアドレスが付いた名前のリンクサーバーを使用する代わりに、FinanceDataLinkProdなどのリソースの名前で新しいリンクサーバーを作成します。次に、到達するサーバーを変更する必要がある場合は、リンクサーバーを更新して新しいサーバーを指すようにします(またはドロップして再作成します)。

  2. 残念ながら、リンクサーバーまたはスキーマのシノニムを作成することはできませんが、リンクサーバーにあるオブジェクトのシノニムを作成することはできます。たとえば、プロシージャ[10.10.100.50].dbo.SPROCEDURE_EXAMPLEはエイリアス化できます。おそらくスキーマdatalinkprodを作成してから、CREATE SYNONYM datalinkprod.dbo_SPROCEDURE_EXAMPLE FOR [10.10.100.50].dbo.SPROCEDURE_EXAMPLE;を作成します。次に、リンクサーバー名を受け入れるストアドプロシージャを記述します。これは、リモートデータベースからすべての潜在的なオブジェクトを照会し、それらの同義語を(再)作成します。すべてのSPと関数は、datalinkprodで始まるシノニム名を使用するために一度だけ書き換えられ、その後、あるリンクサーバーから別のリンクサーバーに変更するにはEXEC dbo.SwitchLinkedServer '[10.10.100.51]';を実行し、ほんの数分で別のリンクサーバーを使用します。

さらに多くのオプションがあります。人間が作成したスクリプトを変更するのではなく、前処理、構成、または間接化の優れた技術を使用することを強くお勧めします。マシンで作成されたスクリプトを自動的に更新することは問題ありません。これは前処理です。手動で物事を行うことはひどいです。

4
ErikE
select text
from syscomments
where text like '%your text here%'
2
Rez.Net

これは、一度にすべてのデータベースから検索できるSQL2008で試しました。

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
1
yenfang chang

汎用の完全な外部相互参照用にこれを書いたところです

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
0
Leif Peterson

Selectステートメントを使用した検索では、検索キーワードが含まれるオブジェクト名のみが生成されます。最も簡単で効率的な方法は、プロシージャ/関数のスクリプトを取得し、生成されたテキストファイルを検索することです。この手法にも従います:).

0
Nitin Daware

これを仕事に使います。 @TEXTフィールドでは[]を省略しますが、すべてを返したいようです...

 SET NOCOUNT ON 
 
 DECLARE @TEXT VARCHAR(250)
 DECLARE @SQL VARCHAR(250)
 
 SELECT @TEXT = '10 .10.100.50 '
 
 CREATE TABLE #results(db VARCHAR(64)、objectname VARCHAR(100)、xtype VARCHAR(10)、definition TEXT)
 
 SELECT @TEXT as 'Search String' 
 DECLARE #databases CURSOR FROM SELECT NAME FROM master..sysdatabases where dbid> 4 
 DECLARE @c_dbname varchar(64)
 OPEN#データベース
 FETCH #databases INTO @c_dbname 
 WHILE @@ FETCH_STATUS -1 
 BEGIN 
 SELECT @SQL = 'INSERT INTO #results' 
 SELECT @SQL = @SQL + 'SELECT' '' + @c_dbname + '' 'AS db、o.name、o.xtype、m.definition' 
 SELECT @SQL = @SQL + 'FROM' + @ c_dbname + '。sys.sql_modules m' 
 SELECT @SQL = @SQL + 'INNER JOIN' + @ c_dbname + '.. sysobjects o ON m.object_id = o.id' 
 SELECT @SQL = @SQL + 'WHERE [定義] LIKE' '%' + @ TEXT + '%' '' 
 EXEC(@SQL)
 FETCH #databases INTO @c_dbname 
 END 
 CLOSE #databases 
 DEALLOCATE #databases 
 
 SELECT * FROM #results db、xtype、objectname 
 DROP TABLE #results 
による結果の順序
0

私は過去にこれらを使用しました:

この特定のケースでは、ストアドプロシージャ全体で特定の文字列を置換する必要がある場合、最初のリンクのほうがおそらく関連性が高くなります。

少し変わったトピック Quick Findアドイン は、SQL Server Management Studioでオブジェクト名を検索する場合にも便利です。 変更されたバージョン がいくつかの改善とともに利用でき、別の 新しいバージョン もCodeplexで利用できます。

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