SQL Server попытается поймать не работает на создание, изменение таблицы и добавление ограничения PK - PullRequest
0 голосов
/ 21 сентября 2018

Это нормально или я что-то упустил?Эти операторы не будут вызывать откат

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

Обратите внимание, что после ... ADD "ActionID" int должно быть большое пространство, должно быть NOT NULL, и после этого следующий оператор попытается создать для него ограничение PK.Так что там произойдет ошибка, и это нормально.Но каким-то образом я получаю сообщение об ошибке в SSMS, предшествующий откат и транзакция остаются активными, но как?почему?

Обратите внимание, что это всего лишь вывод процедуры создания сценариев, которую я создаю и пытаюсь убедиться, что при наличии ошибки никогда не создаст таблицу частично.

Спасибо, Dejan

РЕДАКТИРОВАТЬ 1

ОК, хорошо, но как насчет этого животного, это было сгенерировано самой SSMS:

/* 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

?

Должно быть что-то большее, чем это, в конце я ищу решение, как поместить все это в транзакцию.

1 Ответ

0 голосов
/ 21 сентября 2018

Существует решение для этого:

https://dba.stackexchange.com/questions/29544/rollback-group-of-ddl-statements

и больше об этом:

https://docs.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql?view=sql-server-2017

, которые привели меня к этомурешение:

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

и таблица не была создана из-за ошибки.Довольно круто, не правда ли?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...