我的数据库中有几个存储过程,结构如下:
CREATE PROCEDURE MyProcedure (.....)
AS
DECLARE @myvar NVARCHAR(100);
SET @myvar = (SELECT .... FROM my_table WHERE ....)
GO
我被要求在每个程序中将
my_table
子句中的表 FROM
替换为另一个表。
我进行了很多研究,但我应该创建一个可以独立运行的脚本,但我还没有找到任何合适的东西。例如,我发现
sp_helpTetx
显示了存储过程的源代码,但是有没有办法将其放入变量中以便编辑它?
您可以使用 REDGATE SqlRefactor 等完美运行的工具,或者您可以编写所有存储过程的脚本,用 ALTER 替换 CREATE 命令,然后在您需要的文本中应用其他 REPLACE...
我做了很多次,你必须注意,但它有效......
查找引用该表的所有存储过程(您可以使用 SQL Server 中内置的依赖项或运行查找该表名称的查询,请参阅在 SQL Server 中的存储过程中搜索文本)
使用“ALTER”而不是“CREATE”编写脚本,按 CTRL-H(查找和替换)
执行脚本。
这里有一篇文章概述了如何使用光标和上面提到的 sp_HelpText 来处理这个问题(包括也提到的设置)。
-- 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
CREATE PROCEDURE SelectAllCustomers()
BEGIN
SELECT * FROM customers_custom;
END;
如果 sp_HelpText 返回一个表,为什么不使用游标循环结果并将结果字符串连接在一起?这很讨厌,但可以解决问题。