Reputation: 1009
Is this normal or I am missing something? These statements will not produce rollback
BEGIN TRAN
BEGIN TRY
CREATE TABLE dbo."aCTIONS" ("ID" int NOT NULL IDENTITY(1,1) )
ALTER TABLE "dbo"."aCTIONS"
ADD "Date" datetime
ALTER TABLE "dbo"."aCTIONS"
ADD "Name" nvarchar(50) COLLATE Latin1_General_CI_AS
ALTER TABLE "dbo"."aCTIONS"
ADD "ActionID" int;
ALTER TABLE "dbo"."aCTIONS"
ADD CONSTRAINT PK_aCTIONS_ActionID
PRIMARY KEY NONCLUSTERED ("ActionID")
ALTER TABLE "dbo"."aCTIONS"
ADD "Notes" nvarchar(255) COLLATE Latin1_General_CI_AS;
ALTER TABLE "dbo"."aCTIONS"
ADD CONSTRAINT DF_aCTIONS_Notes DEFAULT (N'MISLIM') FOR "Notes"
ALTER TABLE "dbo"."aCTIONS"
ADD "Consequence_Paid" bit;
ALTER TABLE "dbo"."aCTIONS"
ADD CONSTRAINT DF_aCTIONS_Consequence_Paid DEFAULT ((1)) FOR "Consequence_Paid"
ALTER TABLE "dbo"."aCTIONS"
ADD "Reward_Paid" bit
ALTER TABLE "dbo"."aCTIONS"
ADD "username" int
ALTER TABLE "dbo"."aCTIONS"
ADD "time" time(0)
ALTER TABLE "dbo"."aCTIONS"
ADD "DateOnly" date;
ALTER TABLE "dbo"."aCTIONS"
ADD CONSTRAINT DF_aCTIONS_DateOnly DEFAULT (getdate()) FOR "DateOnly"
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRAN
END CATCH
IF @@TRANCOUNT > 0
COMMIT TRAN
Note that big space after ...ADD "ActionID" int, there should be NOT NULL, and after that next statement will try to create PK constraint on it. So error will happen there, and that is OK. But somehow I get error shown in SSMS, prior rollback, and transaction stays active sill, but how? why?
Please, note that this is just an output of a scripting procedure that I am building and trying to ensure that if error exists would never create table partially.
Thanks, Dejan
EDIT 1
OK, OK, but what about this animal, this was generated by SSMS itself:
/* Toprevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.Stavke ADD
dsad nchar(10) NULL
GO
ALTER TABLE dbo.Stavke SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
?
There has to be something more than this, at the end I am looking for the solution how to put it all in a transaction.
Upvotes: 1
Views: 589
Reputation: 1009
There is a solution for this:
https://dba.stackexchange.com/questions/29544/rollback-group-of-ddl-statements
and more about it:
which lead me to this solution:
SET XACT_ABORT ON;
BEGIN TRAN
BEGIN TRY
CREATE TABLE dbo."aCTIONS" ("ID" int NOT NULL IDENTITY(1,1) )
ALTER TABLE "dbo"."aCTIONS"
ADD "Date" datetime
ALTER TABLE "dbo"."aCTIONS"
ADD "Name" nvarchar(50) COLLATE Latin1_General_CI_AS
ALTER TABLE "dbo"."aCTIONS"
ADD "ActionID" int;
ALTER TABLE "dbo"."aCTIONS"
ADD CONSTRAINT PK_aCTIONS_ActionID
PRIMARY KEY NONCLUSTERED ("ActionID")
ALTER TABLE "dbo"."aCTIONS"
ADD "Notes" nvarchar(255) COLLATE Latin1_General_CI_AS;
ALTER TABLE "dbo"."aCTIONS"
ADD CONSTRAINT DF_aCTIONS_Notes DEFAULT (N'MISLIM') FOR "Notes"
ALTER TABLE "dbo"."aCTIONS"
ADD "Consequence_Paid" bit;
ALTER TABLE "dbo"."aCTIONS"
ADD CONSTRAINT DF_aCTIONS_Consequence_Paid DEFAULT ((1)) FOR "Consequence_Paid"
ALTER TABLE "dbo"."aCTIONS"
ADD "Reward_Paid" bit
ALTER TABLE "dbo"."aCTIONS"
ADD "username" int
ALTER TABLE "dbo"."aCTIONS"
ADD "time" time(0)
ALTER TABLE "dbo"."aCTIONS"
ADD "DateOnly" date;
ALTER TABLE "dbo"."aCTIONS"
ADD CONSTRAINT DF_aCTIONS_DateOnly DEFAULT (getdate()) FOR "DateOnly"
END TRY
BEGIN CATCH
IF (XACT_STATE()) = -1
BEGIN
ROLLBACK TRAN
THROW
END
END CATCH
IF (XACT_STATE()) = 1
COMMIT TRAN
and the table wasn't created because of an error. Pretty cool, isn't it?
Upvotes: 1