SQL Server 프로 시저 / 트리거에서 텍스트를 찾는 방법은 무엇입니까?


173

변경 될 연결된 서버가 있습니다. 일부 절차는 다음과 같이 연결된 서버를 호출합니다 [10.10.100.50].dbo.SPROCEDURE_EXAMPLE. 우리는 이런 종류의 일을하는 방아쇠도 있습니다. 사용하는 모든 장소를 찾아야합니다[10.10.100.50] 그것을 바꾸는 하는 합니다.

SQL Server Management Studio Express에서는 Visual Studio에서 "전체 데이터베이스에서 찾기"와 같은 기능을 찾지 못했습니다. 특별한 sys-select가 필요한 것을 찾는 데 도움이 될 수 있습니까?

답변:


310

다음은 시스템에서 텍스트를 찾기 위해 사용하는 절차의 일부입니다 ....

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
또한 검색 한 값이 포함 된 텍스트를 빠르게 볼 수 있도록이를 결과 집합에 추가 할 수 있습니다. , 부분 문자열 (m.definition, charindex (@Search, m.definition), 100)
Chris Rodriguez

2
@ChrisRodriguez, 좋은 생각이지만, 각 절차 / 트리거 / 함수
KM

제약 조건 ( type = 'C')에는 유효하지 않습니까?
Kiquenet

18

당신은 그것을 찾을 수 있습니다

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

저장 프로 시저 안에 'User'와 같은 텍스트가 포함 된 별개의 저장 프로 시저 이름이 나열됩니다. 더 많은 정보


8
그냥 알고 있어야 syscomments당신이이 경계 중 하나에 걸쳐 분할의 텍스트 당신이있는 거 검색을하는 불운 충분히 그렇다면 테이블에는 8000 문자 덩어리의 값이,이 방법을 찾을 수 없습니다.
ErikE

17

[늦은 대답이지만 희망적으로 유용합니다]

시스템 테이블을 사용한다고해서 항상 100 % 정확한 결과를 얻을 수있는 것은 아니기 때문에 일부 저장 프로 시저 및 / 또는 뷰가 암호화 될 수 있으므로 필요한 데이터를 얻기 위해 DAC 연결을 사용해야 할 수도 있습니다.

암호화 된 객체를 쉽게 처리 할 수있는 ApexSQL 검색 과 같은 타사 도구를 사용하는 것이 좋습니다 .

Syscomments 시스템 테이블은 개체가 암호화 된 경우 텍스트 열에 null 값을 제공합니다.


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
여기에는 질문과 같은 트리거가 포함되지 않습니다
Enkode

뷰, 저장 프로 시저, 사용자 정의 테이블에 유효 합니까? 과에 대한 트리거, 함수, 제약, 규칙, 기본값 ?
Kiquenet

5

이것은 당신을 위해 작동합니다 :

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

제약 조건 ( type = 'C')에는 유효하지 않습니까?
Kiquenet

4

있습니다 많은 당신의 저장 프로 시저, 함수의 텍스트를 수정하는 것보다 더 나은 솔루션, 그리고 때마다 연결된 서버의 변화를 볼. 몇 가지 옵션이 있습니다.

  1. 연결된 서버를 업데이트하십시오. 대신 IP 주소로 이름이 연결된 서버를 사용하여 같은 리소스의 이름으로 새 연결된 서버를 만들 Finance거나 DataLinkProd또는 일부 등. 그런 다음 도달 한 서버를 변경해야 할 경우 새 서버를 가리 키도록 링크 된 서버를 업데이트하십시오 (또는 삭제 한 후 다시 작성하십시오).

  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]';사용하는 경우도 있습니다.

더 많은 옵션이있을 수 있습니다. 사람이 작성한 스크립트를 변경하는 것보다 우수한 전처리, 구성 또는 간접 기술을 사용하는 것이 좋습니다. 머신 생성 스크립트를 자동으로 업데이트하는 것이 좋습니다. 이것은 전처리입니다. 수동으로 작업하는 것은 끔찍합니다.


나는 당신의 제안에 동의합니다. 그러나 OP에서 설명한 것과 같은 상황에서는 여전히 서버 IP가 포함 된 모든 저장 프로 시저를 찾아야합니다. 한 번만 수행해도 손 으로 작업 하는 것은 많은 작업 일 수 있습니다 .
Paul Groke

@PaulGroke 그렇습니다.이 "많은"작품은 확고한 시스템에서 기술적 인 선택이 잘못되어 발생하는 기술적 부채입니다. 이로부터 회복하는 데에는 시간이 걸립니다. 발생한 부채를 상환합니다. 그러나 제 제안은 기술적 인 부를 쌓는 방법입니다. 이제 더 빠르고 민첩하며 나중에 더 많은 시간을 소비합니다. 이것에 관한 몇 가지 아이디어 는 Big Ball of Mud 기사를 읽으십시오 .
ErikE

내가 의미 한 것은 : 다른 사람들이 여기에 게시 한 SELECT 문 중 하나를 사용하여 "채무 상환"작업을 줄임으로써 무엇이 잘못 되었습니까?
Paul Groke

@PaulGroke 연결된 서버를 참조 할 수있는 객체를 빠르게 찾는 방법에는 아무런 문제가 없습니다. 그러나 당신은 "남자에게 물고기를주는 것"보다는 "남자에게 물고기를 가르쳐"라는 오래된 속담을 알고 있습니까? 네. 그 일.
ErikE

@ErikE Thing은-물고기를 잡는 방법을 가르치지 않고 낚시를하면 음식을 얻을 수 있다고 말합니다. 귀하의 답변은 훌륭한 조언이지만 OP가 실제로이를 구현하는 데 도움이되지는 않습니다. 이러한 참조를 찾는 방법을 추가하여 더 나은 디자인으로 대체 할 수 있으면이 답변이 더 좋아질 것입니다.
T. Sar

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

2

이것은 SQL2008에서 시도한 것으로 모든 DB에서 한 번에 검색 할 수 있습니다.

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

나는 이것을 일에 사용합니다. @TEXT 필드에 []를 남겨두고 모든 것을 반환하고 싶은 것 같습니다 ...

NOCOUNT ON 설정

@TEXT VARCHAR (250) 선언
@SQL VARCHAR (250) 선언

@ TEXT = '10 .10.100.50 '선택

CREATE TABLE #results (db VARCHAR (64), 오브젝트 이름 VARCHAR (100), xtype VARCHAR (10), 정의 TEXT)

@TEXT를 '검색 문자열'로 선택
DECLARE #databases master..sysdatabases에서 SELECT NAME을위한 커서 여기서 dbid> 4
    @c_dbname varchar (64) 선언   
    # 데이터베이스 열기
    FETCH #databases INTO @c_dbname   
    @@ FETCH_STATUS-1 동안
    시작
        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
    종료
    CLOSE # 데이터베이스
DEALLOCATE # 데이터베이스

SELECT * FROM #db, xtype, objectname을 기준으로 순서대로 결과
DROP TABLE # 결과

0

나는 과거에 이것을 사용했다 :

이 경우 저장 프로 시저에서 특정 문자열을 바꿔야하는 경우 첫 번째 링크가 더 관련성이 있습니다.

주제와 관련이없는 빠른 찾기 추가 기능은 SQL Server Management Studio를 사용하여 개체 이름을 검색 할 때도 유용합니다. 있어 수정 된 버전을 일부 개선 사용할 수, 또 다른 새로운 버전 뿐만 아니라 다른 유용한 추가 기능으로는 CodePlex에서 사용할 수도는.


0

select 문을 사용하여 검색하면 검색 키워드에 포함 된 개체 이름 만 생성됩니다. 가장 쉽고 효율적인 방법은 절차 / 함수의 스크립트를 얻은 다음 생성 된 텍스트 파일을 검색하는 것입니다. 또한이 기술을 따릅니다.


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

0

그냥 일반 전체 외부 크로스 심판을 위해 이것을 썼습니다.

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

다음 SQL을 사용하여 모든 데이터베이스 오브젝트의 정의 내에서 검색 할 수 있습니다.

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%'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.