I'm trying to write a single T-SQL script which will upgrade a system which is currently in deployment. The script will contain a mixture of:
- New tables
- New columns on existing tables
- New functions
- New stored procedures
- Changes to stored procedures
- New views
- etc.
As it's a reasonably large upgrade I want the script to rollback if a single part of it fails. I have an outline of my attempted code below:
DECLARE @upgrade NVARCHAR(32);
SELECT @upgrade = 'my upgrade';
BEGIN TRANSACTION @upgrade
BEGIN
PRINT 'Starting';
BEGIN TRY
CREATE TABLE x ( --blah...
);
ALTER TABLE y --blah...
);
CREATE PROCEDURE z AS BEGIN ( --blah...
END
GO --> this is causing trouble!
CREATE FUNCTION a ( --blah...
END TRY
BEGIN CATCH
PRINT 'Error with transaction. Code: ' + @@ERROR + '; Message: ' + ERROR_MESSAGE();
ROLLBACK TRANSACTION @upgrade;
PRINT 'Rollback complete';
RETURN;
END TRY
END
PRINT 'Upgrade successful';
COMMIT TRANSACTION @upgrade;
GO
Note - I know some of the syntax is not perfect - I'm having to re-key the code
It seems as though I can't put Stored Procedures into a transaction block. Is there a reason for this? Is it because of the use of the word GO
? If so, how can I put SPs into a transaction block? What are the limitations as to what can go into a transaction block? Or, what would be a better alternative to what I'm trying to achieve?
Thanks