0
我正在進行一些模式遷移,並想知道是否有可能或建議在每個存儲過程中運行每個存儲過程,視圖和函數我的數據庫作爲alter語句來「編譯」它們以確保沒有任何內容被完全破壞。是否有可能在我的所有數據庫對象上運行更改以測試它們
我正在進行一些模式遷移,並想知道是否有可能或建議在每個存儲過程中運行每個存儲過程,視圖和函數我的數據庫作爲alter語句來「編譯」它們以確保沒有任何內容被完全破壞。是否有可能在我的所有數據庫對象上運行更改以測試它們
好吧,我建了一個存儲過程要做到這一點,不是很優雅,但希望別人會發現它有用:
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