如何在SQL Server程序/触发器中查找文本?

我有一个链接服务器,将改变。 有些过程像这样调用链接的服务器: [10.10.100.50].dbo.SPROCEDURE_EXAMPLE 。 我们有触发器也做这种工作。 我们需要find所有使用[10.10.100.50]来改变它。

在SQL Server Management Studio Express中,我没有在Visual Studio中find像“在整个数据库中查找”的function。 一个特殊的系统select能帮我find我需要的东西吗?

这里是我在我的系统上用来查找文本的程序的一部分….

 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%正确的结果,因为可能存在某些存储过程和/或视图被encryption的情况,在这种情况下,您需要使用DAC连接来获取所需的数据。

我build议使用第三方工具,如ApexSQLsearch ,可以轻松地处理encryption对象。

Syscomments系统表将在对象encryption的情况下为文本列赋予空值。

你可以find它

 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 

每次链接服务器发生更改时,修改存储过程,函数和视图的文本都有更好的解决scheme。 这里有一些选项:

  1. 更新链接的服务器。 不要使用以其IP地址命名的链接服务器,而是使用诸如FinanceDataLinkProd之类的资源名称来创build新的链接服务器。 然后,当您需要更改到达哪个服务器时,请更新链接的服务器以指向新的服务器(或者将其删除并重新创build)。

  2. 不幸的是,您不能为链接的服务器或模式创build同义词,您可以为位于链接服务器上的对象创build同义词。 例如,您的过程[10.10.100.50].dbo.SPROCEDURE_EXAMPLE可能会被别名。 也许创build一个模式CREATE SYNONYM datalinkprod.dbo_SPROCEDURE_EXAMPLE FOR [10.10.100.50].dbo.SPROCEDURE_EXAMPLE; ,然后CREATE SYNONYM datalinkprod.dbo_SPROCEDURE_EXAMPLE FOR [10.10.100.50].dbo.SPROCEDURE_EXAMPLE; 。 然后,编写一个接受链接服务器名称的存储过程,该链接服务器名称将查询远程数据库中的所有潜在对象,并(为其创build同义词)。 所有的SP和函数都会被重写一次,以使用从EXEC dbo.SwitchLinkedServer '[10.10.100.51]';开始的同义词名称,然后从一个链接的服务器切换到另一个服务器,您只需执行EXEC dbo.SwitchLinkedServer '[10.10.100.51]'; 并在几秒钟内使用不同的链接服务器。

可能还有更多的select。 我强烈build议使用预处理,configuration或间接的高级技术,而不是更改人为编写的脚本。 自动更新机器创build的脚本是好的,这是预处理。 手动做事情是可怕的。

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

我用这个工作。 尽pipe在@TEXT字段中放弃了[],似乎要返回所有内容…

设置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作为“searchstring”
 DECLARE #databases CURSOR FOR SELECT NAME FROM master..sysdatabases where dbid> 4
     DECLARE @c_dbname varchar(64)   
     OPEN#数据库
     FETCH #databases INTO @c_dbname   
     WHILE @@ 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 [definition] LIKE''%'+ @ TEXT +'%'''   
         EXEC(@SQL)
         FETCH #databases INTO @c_dbname
    结束
    closures#数据库
 DEALLOCATE#数据库

 SELECT * FROM #results按db,xtype,objectnamesorting
 DROP TABLE#结果

我以前用过这些:

  • search所有用户存储过程的表名
  • search并replace所有表的所有列中的SQL Server数据

在这种特殊情况下,如果需要在存储过程中replace特定的string,则第一个链接可能更相关。

有点偏离主题, 快速查找加载项对于使用SQL Server Management Studiosearch对象名称也很有用。 有一个修改后的版本提供了一些改进,另一个更新的版本也可以在Codeplex上使用,还有一些其他有用的加载项。

任何使用select语句进行search都只会产生对象名称,其中包含search关键字。 最简单有效的方法是获得程序/函数的脚本,然后在生成的文本文件中search,我也遵循这个技术:)所以你是精确的精确定位。

这一个我试过SQL2008,它可以一次从所有的数据库search。

 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在所有数据库对象的定义内进行search:

 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%'