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

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

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

13 ответов


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

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

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

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

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

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


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

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

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


-- 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');

Это будет работать для вас:

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

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

  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;. Затем напишите хранимую процедуру, которая принимает имя связанного сервера, который запрашивает все потенциальные объекты из удаленной базы данных и (re)создает синонимы для них. Все ваши SPs и функции переписываются только один раз, чтобы использовать имена синонимов, начинающиеся с datalinkprod, и после этого, чтобы перейти с одного связанного сервера на другой, вы просто делаете EXEC dbo.SwitchLinkedServer '[10.10.100.51]'; и за долю секунды вы используете другой связанный сервер.

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


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

Я использую это для работы. оставьте [], хотя в поле @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 '+@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 [definition] LIKE ''%'+@TEXT+'%'''   
        EXEC(@SQL)
        FETCH #databases INTO @c_dbname
    END
    CLOSE #databases
DEALLOCATE #databases

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

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

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

немного не по теме, то быстрый поиск надстройки это также полезно для поиска имена объектов в среде SQL Server Management Studio. Есть модифицированная версия доступно с некоторыми улучшениями, и еще новая версия также доступны на Codeplex с некоторыми другими полезными надстройками, а также.


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


Это я пробовал в 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

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

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