我正在做一些模式迁移,并且想知道是否可以或可取地运行我的数据库中的每个存储过程、视图和函数作为更改语句来“编译”它们,以确保没有什么是完全的破碎的。
问问题
65 次
1 回答
0
好吧,我建立了一个存储过程来做到这一点,不是很优雅,但希望其他人会发现它很有用:
CREATE PROCEDURE [dbo].[UTIL_RunAlterOnAll]
@debugMessages BIT = 0
AS
BEGIN
BEGIN TRAN
SET NOCOUNT ON
DECLARE @allAlterTexts TABLE (name VARCHAR(256), alterText NVARCHAR(MAX), id INT, type CHAR(2))
DECLARE @rowsInError TABLE (errorMessage NVARCHAR(2048), errorNumber INT, name VARCHAR(256), alterText NVARCHAR(MAX), id INT, type CHAR(2))
;WITH Texts AS
(
SELECT o.name, o.type, sm.definition AS text, o.id
FROM sysobjects AS o
INNER JOIN sys.sql_modules AS sm
ON sm.object_id = o.id
WHERE o.type IN ('P', 'V', 'FN')
)
INSERT INTO @allAlterTexts (name, alterText, id, type)
SELECT name, alterStatement, id, type
FROM
(
SELECT name, REPLACE(text, 'CREATE PROCEDURE', 'ALTER PROCEDURE') AS alterStatement, id, type
FROM Texts AS procs
WHERE procs.type = 'P'
UNION ALL
SELECT name, REPLACE(text, 'CREATE VIEW', 'ALTER VIEW') AS alterStatement, id, type
FROM Texts AS procs
WHERE procs.type = 'V'
UNION ALL
SELECT name, REPLACE(text, 'CREATE FUNCTION', 'ALTER FUNCTION') AS alterStatement, id, type
FROM Texts AS procs
WHERE procs.type = 'FN'
) AS allAlters
DECLARE curs CURSOR FORWARD_ONLY
FOR
SELECT *
FROM @allAlterTexts
DECLARE @name VARCHAR(MAX)
, @alterText VARCHAR(MAX)
, @id INT
, @type VARCHAR(2)
OPEN curs
FETCH NEXT FROM curs
INTO @name, @alterText, @id, @type
WHILE @@FETCH_STATUS = 0
BEGIN
IF @debugMessages = 1
BEGIN
PRINT 'Alter text for @name'
PRINT '-----'
PRINT @alterText
PRINT '-----'
END
BEGIN TRY
IF @debugMessages = 1
BEGIN
PRINT 'Running ' + @name
END
EXEC(@alterText)
IF @debugMessages = 1
BEGIN
PRINT 'Success'
END
END TRY
BEGIN CATCH
IF @debugMessages = 1
BEGIN
PRINT 'ERROR!'
PRINT ERROR_MESSAGE()
PRINT '----'
PRINT 'Text:'
PRINT @alterText
END
INSERT INTO @rowsInError (errorMessage, errorNumber, name, alterText, id, type)
VALUES(LTRIM(RTRIM(ERROR_MESSAGE())), ERROR_NUMBER(), @name, @alterText, @id, @type)
END CATCH
IF @debugMessages = 1
BEGIN
PRINT '-----'
END
FETCH NEXT FROM curs
INTO @name, @alterText, @id, @type
END
CLOSE curs
DEALLOCATE curs
SET NOCOUNT OFF
-- WTF? 3930 means transaction error, these get raised whenever another error is raised,
-- as the transaction is set to invalid
SELECT *
FROM @rowsInError
WHERE errorNumber != 3930
ORDER BY name
ROLLBACK TRAN
END
GO
于 2010-05-07T04:40:00.787 回答