Двойная запись транзакции SQL - PullRequest
0 голосов
/ 08 февраля 2012

Я впервые использую IF Exists и начинаю транзакцию.Я получаю сообщение об ошибке «неверный синтаксис рядом с») в части «Если существует» и неправильный синтаксис рядом с «транзакцией» в конце завершения транзакции.То, что я пытаюсь сделать, это вызвать ошибку, если существует дублирующаяся запись, и если есть ошибка, откройте транзакцию и верните ошибку или верните @@ RowCount. Я не знаю, какую из них выбрать, может ли кто-нибудь исправить мою процедуру и сделатьлюбые корректировки, пожалуйста.

BEGIN TRANSACTION
IF EXISTS (SELECT * FROM Forums WHERE Title = @Title) 
    BEGIN
        RAISERROR ('Duplicate Entry', 16, 1)
    END
ELSE
    BEGIN   
        INSERT INTO Forums(AddedBy, AddedDate, Title, Description, 
               ParentID, Moderated, ImageUrl, UpdatedBy, UpdatedDate, Active, Importance)
        VALUES(@AddedBy, @AddedDate, @Title, null, null, False, null, null, null, True, 0)
        RETURN @@ROWCOUNT
    END


IF @@ERROR <> 0
    BEGIN
        ROLLBACK TRANSACTION
        RETURN @@ERROR
    END

END TRANSACTION 

Ответы [ 3 ]

1 голос
/ 08 февраля 2012

Транзакция не требуется, если вы не хотите применять уровень изоляции или если у вас более одного оператора Update / Insert / Delete, и вам нужно откатить их все в случае возникновения ошибки или зафиксировать их все, если все успешно,

в вашем примере кода есть оператор вставки, который даже не будет выполнен, поэтому вам нечего откатывать

DECLARE @InsertedRows INT = 0

INSERT INTO Forums(AddedBy, AddedDate, Title, Description, ParentID, 
    Moderated, ImageUrl, UpdatedBy, UpdatedDate, Active, Importance)
SELECT @AddedBy, @AddedDate, @Title, null, null, 'False', null, null, null, 'True', 0
WHERE NOT EXISTS (SELECT * FROM Forums WHER Title = @Title)


SET @InsertedRows = @@ROWCOUNT

IF @InsertedRows = 1 
  RETURN 1
ELSE
  RETURN -1
0 голосов
/ 08 февраля 2012

Тебе не нужна транзакция.Однострочная вставка будет либо успешной, либо неудачной (и @@ROWCOUNT в этом случае возвращает только 1).И если у вас есть уникальное ограничение на столбец заголовка (которое, очевидно, должно быть), вам не нужно сначала проверять, хотя это может быть немного более эффективно (мне придется выполнить некоторыетесты для подтверждения, но я уверен, что механизм ошибок довольно дорогой).В любом случае, вот версия с обработкой ошибок на случай, если что-то пойдет не так, как нарушение ограничения заголовка:

IF EXISTS (SELECT 1 FROM dbo.Forums WHERE Title = @Title)
BEGIN
    RAISERROR('Duplicate entry', 16, 1);
    RETURN 2627; -- key constraint violation
END
ELSE
BEGIN
    BEGIN TRY
        INSERT dbo.Forums
        (
          AddedBy, AddedDate, Title, 
          Description, ParentID, 
          Moderated, ImageUrl, UpdatedBy, 
          UpdatedDate, Active, Importance
        )
        SELECT
          @AddedBy,
          @AddedDate,
          @Title, 
          NULL, NULL, 
          'False', -- did you mean 0?
          NULL, NULL, NULL,
          'True', -- did you mean 1?
          0;

        RETURN 1;
    END TRY
    BEGIN CATCH
        DECLARE @msg NVARCHAR(4000) = 'Insert failed ' + ERROR_MESSAGE();
        RAISERROR(@msg, 16, 1);
        RETURN ERROR_NUMBER();
    END CATCH
END
0 голосов
/ 08 февраля 2012
BEGIN TRANSACTION

    IF EXISTS (SELECT * FROM Forums WHERE Title = @Title) 
    BEGIN
        RAISERROR ('Duplicate Entry', 16, 1)
    END
    ELSE
    BEGIN   
          INSERT INTO Forums(AddedBy, AddedDate, Title, Description, ParentID, 
              Moderated, ImageUrl, UpdatedBy, UpdatedDate, Active, Importance)
          VALUES(@AddedBy, @AddedDate, @Title, null, null, False, null, null, null, True, 0)

          COMMIT TRANSACTION

        RETURN @@ROWCOUNT
    END

    IF @@ERROR <> 0
    BEGIN
        ROLLBACK TRANSACTION
        RETURN @@ERROR
    END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...