2013-08-22 70 views
3

我想在事務中包裝一些操作,以便我可以確定是否應該在最後一步中刪除表。這是我到目前爲止有:Commit @@ ROWCOUNT

--select the DB 
    use DB1 


    --if the table exists, we want to delete it first 
    IF (EXISTS (SELECT * 
        FROM INFORMATION_SCHEMA.TABLES 
        WHERE TABLE_SCHEMA = 'dbo' 
        AND TABLE_NAME = 'VV')) 
    BEGIN 
     drop table dbo.VV 
    END 

BEGIN TRAN 

    SELECT field1 
      ,field2 
      ,field3 

    INTO dbo.vv 
     FROM vvr A 
    WHERE A.field1 <> 'GEN' 
    AND A.field2 <> 'NO DATA' 
    AND A.field3 <> '(BLANK) NO' 

PRINT 'ROW1:' + CAST(@@ROWCOUNT as varchar(11)) 
IF @@ROWCOUNT = 0 
     ROLLBACK TRAN 
    ELSE 
     COMMIT TRAN 


    UPDATE dbo.vv 
    SET dbo.field1 = vvr.field1 
    FROM dbo.vv 

PRINT 'ROW2:' + CAST(@@ROWCOUNT as varchar(11)) 

IF @@ROWCOUNT = 0 
     ROLLBACK TRAN 
    ELSE 
     COMMIT TRAN 

當我運行這個沒有事務的語句,它運行得很好,所以我知道SQL的作品,但是當我添加事務的語句,它不能告訴我,表VV沒有按不存在。當我選擇VV時,它絕對沒有了。

一旦我得到上面的運行良好,我會在最後添加一個語句來刪除表vvr,但我還沒有那麼遠。

+0

除了user172839的回答:'如果'插入後將提交或回滾事務,但更新後的下一個'如果'將嘗試做同樣的和失敗因爲沒有交易。只有在兩個操作都成功的情況下才需要提交? –

+0

是的,我想要做的是確保前面的語句是成功的,如果是的話,刪除最後一個表(不包括在上面的語句中)。 – Baub

回答

7

如果要執行基於單個語句影響的行數多的動作,那麼你需要立即捕捉值到你自己的變量:

DECLARE @rc int 
SELECT field1 
     ,field2 
     ,field3 

INTO dbo.vv 
    FROM vvr A 
WHERE A.field1 <> 'GEN' 
AND A.field2 <> 'NO DATA' 
AND A.field3 <> '(BLANK) NO' 

SET @rc = @@ROWCOUNT 
PRINT 'ROW1:' + CAST(@rc as varchar(11)) 
IF @rc = 0 
    ROLLBACK TRAN 
ELSE 
    COMMIT TRAN 

即使是簡單的語句像PRINT的事業@@ROWCOUNT將被分配一個新的值(在這種情況下,0)

+0

我使用了這種格式,儘管我改爲@ERROR。我認爲我的一部分困惑來自於我試圖在每個動作之後測試@@ ERROR,這導致了一個問題,而且沒有必要。所以我剛剛在發言結束時就像在這裏一樣使用它。 – Baub

2

PRINT 'ROW1:' + CAST(@@ROWCOUNT as varchar(11))

此行重置@@ ROWCOUNT。如果在表中插入了50條記錄,則打印語句將返回50,但是當您在下一行中引用@@ ROWCOUNT時,該值將返回0,因此,由於執行回滾操作,該表永遠不會存在

這會導致下一行(UPDATE語句)始終失敗。

0

我在那裏的PRINT語句只是用於開發,我打算一旦完成這些工作就刪除它們。所以我把它們拿出來了,SELECT INTO和UPDATE語句運行正常,但是沒有一個DROP語句起作用。

在我的代碼,我增加了一個頂部DROP TABLE語句是這樣的:

IF @@ROWCOUNT > 0 
BEGIN 
    drop table dbo.VVR 
END 

IF @@ROWCOUNT > 0 COMMIT TRAN 

如果我在上面運行DROP TABLE語句,然後運行整個過程,我不得到任何類型的錯誤,只是更新表,因爲我期望然後停止。

+0

由於user172839正試圖向您指出,因爲幾乎每個語句都會導致將@@ ROWCOUNT設置爲新值,所以不能連續引用@@ ROWCOUNT兩次(在特殊情況之外)。例如。 '從sys.objects中選擇頂部1 *; print @@ ROWCOUNT; print @@ ROWCOUNT;'從'sys.objects'中選擇1行,然後打印1然後打印0 - 因爲第一個'print'導致'@@ ROWCOUNT'被重置爲0. –