2016-02-12 33 views
1

這是我的代碼。這很簡單:第一個INSERT失敗,而最後兩個成功。我認爲BEGIN/COMMIT TRAN之間的所有內容都被認爲是成功或失敗的一項交易?

在我繼續之前,我想澄清一點,我明白我可以插入IF statement@@ERRORBEGIN ROLLBACK這將解決問題。我知道這個問題怎麼解決。

由於腳本中的兩個INSERT都在BEGIN/COMMIT TRAN之間,所以我認爲這將被視爲單個事務。所以在我的情況下,由於1st INSERT失敗,所以我認爲以下INSERT s不會執行或不會被提交。看來情況並非如此。

BEGIN TRANCOMMIT TRAN的用途是否能夠在它們之間使用@@ERROR函數和/或ROLLBACK TRAN

IF OBJECT_ID('tempdb..#testTable') IS NOT NULL DROP TABLE #testTable 
create table #testTable 
(
    Id int not null, 
    Name varchar(100) 
) 

BEGIN TRAN T1; 
insert into #testTable select null, 'Joe'; 
-- select @@ERROR 
if @@ERROR = 0 
BEGIN 
    insert into #testTable select 1, 'Bob'; 
    insert into #testTable select 2, 'Ralph'; 
END 
COMMIT TRAN T1; 
select * From #testTable 

謝謝。

回答

3

表變量(@testTable)do 不支持支持交易。

如果您需要事務性支持,請改用常規臨時表(#testTable)。

+0

是否有一些這方面的資料? –

+3

@ roryap - https://msdn.microsoft.com/en-us/library/ms175010.aspx「因爲表變量的作用域有限,不是持久數據庫的一部分,所以它們不受事務回滾的影響。」 –

+2

謝謝@SeanLange! (我正在尋找 - 你發現:-)) –

2

爲了使這一系列插入你需要使用TRY一個「全有或全無」的局面/ CATCH

IF OBJECT_ID('tempdb..#testTable') IS NOT NULL DROP TABLE #testTable 
create table #testTable 
(
    Id int not null, 
    Name varchar(100) 
) 

begin try 
    BEGIN TRAN T1; 
     insert into #testTable select 1, 'Bob'; 
     insert into #testTable select null, 'Joe'; 
     insert into #testTable select 2, 'Ralph'; 
    COMMIT TRAN T1; 
end try 

begin catch 
    select 'Error encountered. No rows added' 
    rollback transaction 
end catch 

select * From #testTable 
+0

正如我在下面的評論和初始文章中提到的,我明白如何解決這個問題。 – rbhat

+0

我只是說我**認爲** BEGIN/END TRAN是一種接受多個事務(即3 INSERT'S)並將它們「轉換」爲一個成功或失敗的單元的方法。 – rbhat

+0

顯然,'BEGIN TRAN'和'COMMIT TRAN'能夠使用'@@ ERROR'函數或'try/catch'來檢查錯誤,然後'ROLLBACK TRAN'。 – rbhat

相關問題