2010-11-17 27 views
0

HI,Perl的DBI - 獲取每個受影響的語句記錄在交易

我用perl DBI做()將執行以下SQL塊像下面這執行SQL SERVER 2005

eval { 
      my $result = do(<<SQL); 
      BEGIN TRAN 

      UPDATE table1 SET 
      col1 = 999 where date = '2010-08-27' 

      DELETE FROM table1 
      where date = '2010-08-30' 

      COMMIT TRAN 
SQL 
    $logger->info($result); 
}; 

現在我可以看到返回值$ result僅包含受第一個更新語句影響的行。所以我沒有關於刪除行的任何信息,但是我可以看到行確實在數據庫中被刪除。

一般來說,如果我在BEGIN TRAN,COMMIT TRAN塊內有INSERT,DELETE,UPDATE語句,並且如果整個塊將由DBI do()方法提交,我需要知道插入的語句的確切數目,更新的報表數量和刪除的報表數量。

我知道SQL SERVER的@@ ROWCOUNT會給我在每個語句後受到影響的行,但這是一個SQL服務器變量,它只會在塊內部可見。是否有可能獲得數據到Perl?

任何幫助?

回答

2

要得到@@ROWCOUNT的值,需要在「COMMIT TRAN」之前添加SELECT @@ROWCOUNT 'rowcount'作爲最後一個命令,那麼整個SQL將返回1行與1個「rowcount」列結果集合。

唯一需要注意的是,由於do()方法不爲你提供的結果集,你需要切換到prepare()/fetchrow_array()/fetchrow_array()替代,或者用的包裝方法,如nsql()一個從DB庫,如果這些都可用。

有關詳細插入/更新/刪除故障,只需保存那些@@ ROWCOUNTs到變量之後,插入/更新/刪除,然後選擇計數算賬:

declare @update_count int 
declare @delete_count int 

UPDATE table1 SET 
col1 = 999 where date = '2010-08-27' 
SELECT @update_count = @@ROWCOUNT 

DELETE FROM table1 
where date = '2010-08-30' 
SELECT @delete_count = @@ROWCOUNT 

SELECT @update_count 'update_count', @delete_count '@delete_count' 
1

正在使用哪種數據庫訪問方法?是否有任何理由不將事務邏輯移到T-SQL之外?

如果您使用沿着這些路線DBI的東西應該滿足你的要求:

eval { 
    $dbh->begin_work; 
     $dbh->do("CREATE TABLE #temp (col1 INTEGER, date DATETIME);"); 

     # Inserts 
     my $inserted = $dbh->do("INSERT INTO #temp VALUES (1,'2010-08-27');"); 
     $inserted += $dbh->do("INSERT INTO #temp SELECT 999,'2010-08-27' UNION SELECT 5, '2010-08-30';"); 

     # Updates 
     my $updated = $dbh->do("UPDATE #temp SET col1 = 999 WHERE date = '2010-08-27';"); 

     # Deleted 
     my $deleted = $dbh->do("DELETE FROM #temp WHERE date = '2010-08-30';"); 
    $dbh->commit; 

    print "Inserted $inserted rows.\n"; 
    print "Updated $updated rows.\n"; 
    print "Deleted $deleted rows.\n"; } 

這個片段不考慮使得數據庫連接,錯誤處理或關閉連接,但DBI文檔應該在那裏幫助。 http://metacpan.org/pod/DBI

如果您計劃執行多個非選擇語句,您可能還需要查看prepare和bind_param DBI方法。

+0

我有一大堆的INSERT, DELETE,UPDATE作爲單個事務運行。即爲什麼我需要在T-SQL BEGIN TRAN和COMMIT TRAN塊中包含所有語句。所以我能想到的唯一方法是將整個SQL作爲一個字符串,準備()它,執行並獲取返回的結果,這將有計數。如果在begin_work內部有多個do,並且按照您的寫法提交,則會產生相同的效果。完全是ACID嗎? – 2010-11-18 03:22:36

+0

是的,在begin_work和rollback/commit之間使用多個do語句與T-SQL中的BEGIN TRANSACTION和ROLLBACK TRANSACTION/COMMIT TRANSACTION塊具有相同的效果。您可以通過用$ dbh - > {AutoCommit} = 0 ;,替換$ dbh-> begin_work來測試此行爲,然後在不同的DML操作之後添加提交和回滾。無論事務是回滾還是已提交,打印都將顯示受影響的行數,但轉儲表結果應顯示預期數據。 – Bryan 2010-11-18 17:32:15

相關問題