使用搜索/遍历所有的存储过程替换最快/最简单的方法

问题描述 投票:11回答:13

其实,这是一个2部分的问题。

  1. 是否有可能使用某种功能通过每一个存储过程来搜索字符串,并可能取代它,就像一个标准的查找/替换功能?
  2. 如果你把所有的存储过程的代码包括这样[db1].[dbo].[table1]完整的数据库路径和更改数据库名称[db2]是有SQL服务器的方式来自动更新从[db1]表中的所有代码[db2]?或者它必须手动完成?
sql sql-server sql-server-2008
13个回答
10
投票

相关搜索:如果你需要按名称查找数据库对象(如表,列,触发器) - 看看在自由红门工具,称为SQL Search它做到这一点 - 它搜索整个数据库的任何类型的字符串(S) 。

这对任何DBA或数据库开发人员有很大必备的工具 - 为什么我已经提到它的绝对自由使用任何类型的使用?

此工具不支持替换文本,但是 - 但即使只是能够找到所有相关的存储过程(或其他数据库对象)是非常有帮助真的!


0
投票

有没有办法用内置的功能来做到这一点。虽然今天不帮你,我建议改变所有引用到synonyms,而你在里面。这样,当再次出现这种情况在未来(它会再次发生),你的所有外部引用的是在一个地方,容易更新。顺便说一句,我对后者blog post


0
投票

如果你有停机时间可用。

进入“生成脚本”,并为所有的存储过程,你要编辑“创造”的脚本。

在脚本中替换文本,并只删除并重新创建所有的人。


0
投票

这里有一个我今天撰文称,以帮助服务器升级项目。

搜索在服务器上的所有用户数据库都存储的特效和意见,并自动替换为另一个搜索字符串。理想的改变硬编码的链接服务器名称等:

set nocount on

if OBJECT_ID('tempdb..#dbs') is not null
    drop table #dbs

if OBJECT_ID('tempdb..#objects') is not null
    drop table #objects

declare @find as nvarchar(128) = 'Monkey'
declare @replace as nvarchar(128) = 'Chimp'

declare @SQL as nvarchar(max)
declare @current_db as sysname
declare @current_schema as sysname
declare @current_object as sysname
declare @current_type as char(2)
declare @current_ansi as bit
declare @current_quot as bit
declare @fullname as sysname
declare @preamble as nvarchar(128)

create table #objects
    (
     dbname sysname, 
     schemaname sysname, 
     objname sysname,
     objtype char(2),
     ansinulls bit,
     quotedidentifier bit
     )
create unique clustered index i on #objects (dbname, schemaname, objname)

select [name] into #dbs 
from master.sys.databases
where [name] not in ('master','tempdb','model','msdb','ReportServer','ReportServerTempDB', 'SSISDB')


declare db_cursor cursor for select [name] from #dbs order by [name]
open db_cursor
fetch next from db_cursor into @current_db

while @@FETCH_STATUS = 0
begin
    set @SQL = 'insert into #objects select ''' + @current_db + ''', s.[name], o.[name], o.[type], m.uses_ansi_nulls, m.uses_quoted_identifier from ' + @current_db + '.sys.sql_modules as m '
             + 'join ' + @current_db + '.sys.objects AS o ON m.object_id = o.object_id '
             + 'join ' + @current_db + '.sys.schemas AS s ON o.schema_id = s.schema_id '
             + 'where m.definition like ''%' + @find + '%'' and type in (''P'', ''V'') and is_ms_shipped = 0 order by s.[name], o.[name]'

    exec sp_executeSQL @SQL
    fetch next from db_cursor into @current_db
end
close db_cursor
deallocate db_cursor



declare obj_cursor cursor for select dbname, schemaname, objname, objtype, ansinulls, quotedidentifier from #objects order by dbname, objname
open obj_cursor
fetch next from obj_cursor into @current_db, @current_schema, @current_object, @current_type, @current_ansi, @current_quot

while @@FETCH_STATUS = 0
begin
    set @fullname =  @current_db + '.' + @current_schema + '.' + @current_object

    set @preamble = CASE WHEN @current_ansi = 1 THEN 'SET ANSI_NULLS ON' ELSE 'SET ANSI_NULLS OFF' END + '; ' 
                  + CASE WHEN @current_quot = 1 THEN 'SET QUOTED_IDENTIFIER ON' ELSE 'SET QUOTED_IDENTIFIER OFF' END + '; ' 

    print 'Altering ' + @fullname 

    if @current_type = 'P'
    begin
        set @SQL = 'use ' + @current_db + '; ' + @preamble + 'declare @newproc nvarchar(max);'
                 + 'set @newproc = REPLACE(REPLACE(OBJECT_DEFINITION(OBJECT_ID(''' + @fullname + ''')), ''' + @find + ''', ''' + @replace + '''), ''CREATE PROCEDURE'', ''ALTER PROCEDURE''); '
                 + 'exec sp_executeSQL @newproc' 
        exec sp_executeSQL @SQL               
    end

    if @current_type = 'V'
    begin
        set @SQL = 'use ' + @current_db + '; ' + @preamble + 'declare @newproc nvarchar(max);'
                 + 'set @newproc = REPLACE(REPLACE(OBJECT_DEFINITION(OBJECT_ID(''' + @fullname + ''')), ''' + @find + ''', ''' + @replace + '''), ''CREATE VIEW'', ''ALTER VIEW''); '
                 + 'exec sp_executeSQL @newproc'        
        exec sp_executeSQL @SQL
    end
    fetch next from obj_cursor into @current_db, @current_schema, @current_object, @current_type, @current_ansi, @current_quot
end
close obj_cursor
deallocate obj_cursor

它也处理的特质ANSI_NULL和QUOTED_IDENTIFIER设置,并可以扩展到处理不同类型的功能。

不过要小心!拥有权利的同时也被赋予了重大的责任...


-1
投票

嗯,删除和重建的所有程序的工作,遗憾的是它坠毁于这对于一个相当大的工厂SCADA依靠SQL服务器。

它保存了一点努力单独编辑它们,工厂只是停滞不前,直到我重新启动服务器。

然依吾小心谨慎。我是公平crapping自己一会儿那里。


38
投票

从SSMS对象资源管理器详细信息窗口,打开存储过程的文件夹。选择(可以多选在此窗口中,这是相当多的对象资源管理器详细信息窗口的唯一目的),并点击右键,选择到脚本删除并创建的所有对象。现在,你可以做一个查找/替换此,更换所有你在一个需要去执行它。

编辑:我blogged about this solution


22
投票

下旬的一个,但希望有用。

还有,可以发现并命名的数据库对象free search tool from ApexSQL

他们说,它拥有智能重命名选项,将查找/替换某个对象的所有事件,如表,函数或存储过程。

我要补充一点,我还没有使用重命名功能,但我可以证实,搜索是合作得非常好。

另外,我不ApexSQL关联,但我使用他们的工具。


5
投票
  1. 导出所有SP到文件。使用您喜欢的文本编辑工具来查找/替换。通过执行脚本更新数据库(只要你不重新命名程序)。
  2. 如果你明确地定义完整的数据库路径,您需要手动(见上文)更新的存储过程。如果不包括数据库名,或使用链接的服务器或类似的,没有变化是必要的。

4
投票

存储过程不能到位而不先脚本出来作为ALTER PROCEDURE报表更新(或DROP/CREATE,但我更喜欢对ALTER PROCEDURE..more在某一时刻)。好消息是,你可以编写脚本程序全部通过SSMS单个文件。 DDL语句最初将CREATE PROCEDURE,你会想用ALTER PROCEDURE更换,与其他一起改变。

虽然你可以或者脚本程序作为DROP/CREATE,我不喜欢大量的脚本这样做,因为这往往会导致相关性错误。

至于你的问题的第2部分,你需要编辑任何数据库路径手动更改通过脚本。


3
投票

您可以搜索使用此存储过程定义的文本

SELECT 
  Name 
FROM 
  sys.procedures 
WHERE 
   OBJECT_DEFINITION(OBJECT_ID) LIKE '%YourSearchText%'

更换通常是一个坏主意,因为你不知道你会在存储过程中查找文本的情况下。这可能是通过尽可能PowerShell脚本虽然。

我喜欢这个解决方案,任何人,因为我是舒适的查询 - 因此,找到在所有存储的特效,是在架构(x)和数据库(y)和名称以启动文本(z)是一个相当容易和直观查询。


2
投票

我发现这个脚本,您可以定义搜索和替换文本和简单地运行它来获取文本中的所有步骤更换一次。我希望这将帮助你在大头。

-- set "Result to Text" mode by pressing Ctrl+T
SET NOCOUNT ON

DECLARE @sqlToRun VARCHAR(1000), @searchFor VARCHAR(100), @replaceWith VARCHAR(100)

-- text to search for
SET @searchFor = '[MY-SERVER]'
-- text to replace with
SET @replaceWith = '[MY-SERVER2]'

-- this will hold stored procedures text
DECLARE @temp TABLE (spText VARCHAR(MAX))

DECLARE curHelp CURSOR FAST_FORWARD
FOR
-- get text of all stored procedures that contain search string
-- I am using custom escape character here since i need to espape [ and ] in search string
SELECT DISTINCT 'sp_helptext '''+OBJECT_SCHEMA_NAME(id)+'.'+OBJECT_NAME(id)+''' ' 
FROM syscomments WHERE TEXT LIKE '%' + REPLACE(REPLACE(@searchFor,']','\]'),'[','\[') + '%' ESCAPE '\'
ORDER BY 'sp_helptext '''+OBJECT_SCHEMA_NAME(id)+'.'+OBJECT_NAME(id)+''' '

OPEN curHelp

FETCH next FROM curHelp INTO @sqlToRun

WHILE @@FETCH_STATUS = 0
BEGIN
   --insert stored procedure text into a temporary table
   INSERT INTO @temp
   EXEC (@sqlToRun)

   -- add GO after each stored procedure
   INSERT INTO @temp
   VALUES ('GO')

   FETCH next FROM curHelp INTO @sqlToRun
END

CLOSE curHelp
DEALLOCATE curHelp

-- find and replace search string in stored procedures 
-- also replace CREATE PROCEDURE with ALTER PROCEDURE
UPDATE @temp
SET spText = REPLACE(REPLACE(spText,'CREATE PROCEDURE', 'ALTER PROCEDURE'),@searchFor,@replaceWith)

SELECT spText FROM @temp
-- now copy and paste result into new window
-- then make sure everything looks good and run
GO

下面是引用链接: http://www.ideosity.com/ourblog/post/ideosphere-blog/2013/06/14/how-to-find-and-replace-text-in-all-stored-procedures


1
投票

我只是运行此代码找到的所有存储过程特定的文本:

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 '%textToFind%'
   or m.definition Like '%\[ifTextIsAColNameWithBrackets\]%' ESCAPE '\';

1
投票

更新我才意识到在大卫的答案的链接包括搜索功能。再次,这是一个伟大的答案。


David Atkinson's答案是伟大的,只是要添加搜索的一部分。 (不知道当搜索SSMS中添加,我的版本SSMS V17.9.1的)

相反,由一个选择存储过程之一,我可以做搜索。

  • 搜索需要通配符,类似“喜欢”在SQL

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.