Как найти текст внутри процедур / триггеров 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% правильные результаты, потому что может быть вероятность того, что некоторые хранимые процедуры и/или представления зашифрованы, и в этом случае вам нужно будет использовать DAC подключение для получения необходимых данных.
Я бы рекомендовал использовать сторонний инструмент, такой как ApexSQL Search это может иметь дело с зашифрованными объектами легко.
система 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
здесь много лучшие решения, чем изменение текста хранимых процедур, функций и представлений при каждом изменении связанного сервера. Вот несколько вариантов:
обновить связанный сервер. Вместо использования связанного сервера с его 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;. Затем напишите хранимую процедуру, которая принимает имя связанного сервера, который запрашивает все потенциальные объекты из удаленной базы данных и (повторно)создает синонимы для них. Все ваши SPs и функции переписываются только один раз, чтобы использовать имена синонимов, начиная сdatalinkprod, и после этого, чтобы перейти от одного связанного сервера к другому, вы просто делаетеEXEC dbo.SwitchLinkedServer '[10.10.100.51]';и через долю секунды вы используете другой связанный сервер.там может быть еще больше вариантов. Я настоятельно рекомендую использовать превосходные методы предварительной обработки, настройки или косвенной обработки, а не изменять написанные человеком сценарии. Автоматическое обновление машинные скрипты-это нормально, это предварительная обработка. Делать что-то вручную-это ужасно.
Я использую это для работы. оставьте [], хотя в поле @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 во всех столбцах всех таблиц
в этом конкретном случае, когда вам нужно заменить определенную строку в хранимых процедурах, первая ссылка, вероятно, более актуальна.
немного не по теме, то быстрый поиск надстройки это также полезно для поиска имена объектов в среде среда 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%'
Comments