私はいくつかのスキーマ移行を行っている最中です。データベース内のすべてのストアドプロシージャ、ビュー、および関数を、すべてを「コンパイル」して完全に何もないことを確認するための変更ステートメントとして実行することが可能または推奨されるかどうかを知りたいです。壊れた。
1 に答える
0
まあ、私はこれを行うために sproc を作成しましたが、あまりエレガントではありませんが、うまくいけば他の誰かがそれを役に立つと思うでしょう:
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 に答える