2013-03-29 6 views
1

У меня есть две таблицы - tblRequests и tblData. tblRequests имеет первичный ключ recID, а tblData имеет внешний ключ к этому первичному ключу, который называется requestRecID.SQL Server 2005: попробуйте Catch с обновлением на детской таблице

tblRequests У меня есть уникальный указатель на два столбца, который мешает пользователям вводить повторяющиеся строки.

Проблема: когда я пытаюсь дублировать вставку на tblRequests, она ошибается, как и ожидалось, но мой tblData все еще обновляет внешний ключ.

Итак, как я могу сказать «Не обновлять tblData, если tblRequests вставить не произошло»?

Выполнение некоторых исследований, кажется, try/catch будет в порядке, но я не совсем знаком с этим уровнем SQL.

Мой код ниже:

CREATE Procedure [dbo].[spInsert] 
(
    @vOpID varchar(3), 
    @vSNumb varchar(12) 
) 
AS 
    Declare @vRecID int 
BEGIN 
    BEGIN TRANSACTION 
     Insert tblRequests 
     (
     opID, 
     SNumb 
     ) 
     Values 
     (
     @vOpID, 
     @SNumb 
     ) 

     Set @vRecID = IDENT_CURRENT ('tblRequests') 

    COMMIT TRANSACTION; 
    BEGIN TRANSACTION 
     Update tblData 
     Set requestRecID = @vRecID 
     Where SNumb = @SNumb And opID = @vOpID 
    COMMIT TRANSACTION; 
END 

ответ

2

Вам нужно будет что-то вроде этого:

  • один транзакцию, которая охватывает обе операции (потому что вы действительно хотите, чтобы либо были обе операции успеха, или затем откатить все - не только часть транзакции ...)

  • внутри a TRY...CATCH - если первая операция (INSERT) вызывает ошибку, она перейдет прямо в блок CATCH и не выполнит второй оператор, и он откатит транзакцию.

Код:

CREATE Procedure [dbo].[spInsert] 
(
    @vOpID varchar(3), 
    @vSNumb varchar(12) 
) 
AS 
BEGIN 
    DECLARE @vRecID INT 

    BEGIN TRANSACTION 
    BEGIN TRY 
     INSERT INTO dbo.tblRequests(opID, SNumb) 
     VALUES(@vOpID, @SNumb) 

     SET @vRecID = SCOPE_IDENTITY() 

     UPDATE dbo.tblData 
     SET requestRecID = @vRecID 
     WHERE SNumb = @SNumb AND opID = @vOpID 

     COMMIT TRANSACTION 
    END TRY 
    BEGIN CATCH 
     SELECT 
      ERROR_NUMBER() AS ErrorNumber, 
      ERROR_SEVERITY() AS ErrorSeverity, 
      ERROR_STATE() AS ErrorState, 
      ERROR_PROCEDURE() AS ErrorProcedure, 
      ERROR_LINE() AS ErrorLine, 
      ERROR_MESSAGE() AS ErrorMessage 

     ROLLBACK TRANSACTION 
    END CATCH 
END 
+0

Отлично! Каждый сценарий работает как ожидается. Спасибо! – SeanFlynn

Смежные вопросы