Как найти текст внутри процедур/триггеров SQL Server?

У меня есть linkedserver, который изменится. Некоторые процедуры называют связанный сервер следующим образом: [10.10.100.50].dbo.SPROCEDURE_EXAMPLE. У нас есть триггеры, которые также выполняют такую ​​работу. Нам нужно найти все места, в которых используется [10.10.100.50], чтобы изменить его.

В SQL Server Management Studio Express я не нашел такую ​​функцию, как "найти всю базу данных" в Visual Studio. Может ли специальный sys-select помочь мне найти то, что мне нужно?

Ответ 1

вот часть процедуры, которую я использую в своей системе, чтобы найти текст....

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 '%'[email protected]+'%'
    ORDER BY 2,1

Ответ 2

[Поздний ответ, но, надеюсь, полезно]

Использование системных таблиц не всегда дает 100% правильные результаты, потому что может быть вероятность, что некоторые хранимые процедуры и/или представления зашифрованы, и в этом случае вам нужно будет использовать DAC для получения необходимых данных.

Я бы рекомендовал использовать сторонний инструмент, такой как ApexSQL Search, который легко справляется с зашифрованными объектами.

Системная таблица Syscomments будет давать пустое значение для текстового столбца в случае, если объект зашифрован.

Ответ 3

Вы можете найти его как

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

В нем будут перечислены различные имена хранимых процедур, содержащие текст, подобный "Пользователь" внутри хранимой процедуры. Дополнительная информация

Ответ 4

-- 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 '%'[email protected]+'%'
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 '%'[email protected]+'%'
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 '%'[email protected]+'%'
      AND (ROUTINE_TYPE = 'function' OR ROUTINE_TYPE = 'procedure');

Ответ 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

Ответ 6

Есть более лучшие решения, чем изменение текста ваших хранимых процедур, функций и представлений при каждом изменении связанного сервера. Вот несколько вариантов:

  • Обновить связанный сервер. Вместо использования связанного сервера с его IP-адресом создайте новый связанный сервер с именем ресурса, таким как Finance или DataLinkProd или некоторые из них. Затем, когда вам нужно изменить, какой сервер достигнут, обновите связанный сервер, чтобы указать на новый сервер (или отпустите его и заново создайте).

  • К сожалению, вы не можете создавать синонимы для связанных серверов или схем, вы МОЖЕТЕ делать синонимы для объектов, расположенных на связанных серверах. Например, ваша процедура [10.10.100.50].dbo.SPROCEDURE_EXAMPLE может быть выполнена с помощью псевдонимов. Возможно, создайте схему DataLinkProd, затем CREATE SYNONYM datalinkprod.dbo_SPROCEDURE_EXAMPLE FOR [10.10.100.50].dbo.SPROCEDURE_EXAMPLE;. Затем напишите хранимую процедуру, которая принимает имя связанного сервера, которое запрашивает все потенциальные объекты из удаленной базы данных и (re) создает для них синонимы. Все ваши SP и функции переписываются только один раз, чтобы использовать имена синонимов, начиная с DataLinkProd, и когда-либо после этого, чтобы перейти с одного связанного сервера на другой, вы просто выполняете EXEC dbo.SwitchLinkedServer '[10.10.100.51]'; и за долю секунды, которую используете другой связанный сервер.

Может быть еще больше вариантов. Я настоятельно рекомендую использовать превосходные методы предварительной обработки, конфигурации или косвенности, а не изменять написанные человеком сценарии. Автоматическое обновление созданных машиной сценариев в порядке, это предварительная обработка. Делать вещи вручную ужасно.

Ответ 7

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

Ответ 8

Я использую этот для работы. оставьте поле [], хотя в поле @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 FOR SELECT NAME FROM master..sysdatabases where dbid>4
    DECLARE @c_dbname varchar(64)   
    OPEN #databases
    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 '[email protected]_dbname+'.sys.sql_modules m '   
        SELECT @SQL = @SQL + ' INNER JOIN '[email protected]_dbname+'..sysobjects o ON m.object_id=o.id'   
        SELECT @SQL = @SQL + ' WHERE [definition] LIKE ''%'[email protected]+'%'''   
        EXEC(@SQL)
        FETCH #databases INTO @c_dbname
    END
    CLOSE #databases
DEALLOCATE #databases

SELECT * FROM #results order by db, xtype, objectname
DROP TABLE #results

Ответ 9

Я использовал их в прошлом:

В этом конкретном случае, когда вам нужно заменить определенную строку на хранимые процедуры, первая ссылка, вероятно, более актуальна.

Немного не по теме, Quick Add add in также полезна для поиска имен объектов в SQL Server Management Studio. Там измененная версия доступна с некоторыми улучшениями, а другая более новая версия также доступны на Codeplex с некоторыми другими полезными надстройками.

Ответ 10

Любой поиск с помощью оператора select дает вам только имя объекта, в котором содержится ключевое слово поиска. Самый простой и эффективный способ - получить script процедуры/функции, а затем выполнить поиск в сгенерированном текстовом файле, я также следую этой методике:) Итак, вы точно точны.

Ответ 11

Это я попытался в 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='[email protected]
    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

Ответ 12

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

Ответ 13

Только что написал это для общего полного внешнего перекрестного ссылки

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,'''[email protected]+''', o.name,'''[email protected]+'''
        from '[email protected]+'.dbo.syscomments c
        join '[email protected]+'.dbo.sysobjects o on c.id=o.id
        where o.xtype in (''V'',''P'',''FN'',''TR'')
        and (text like ''%'[email protected]+'.%''
          or text like ''%'[email protected]+'].%'')'
        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

Ответ 14

Вы можете искать в определениях всех объектов базы данных, используя следующий 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%'