2009-02-16 43 views
3

我想對生產數據庫運行更新查詢,並且想盡可能保證安全。我期待做以下事情在MySQL中是否存在SQL Server的@@錯誤的等效項

BEGIN TRANSACTION 
    UPDATE table_x SET col_y = 'some_value' 
    . 
    . 
    . 
IF (@@error <> 0) 
BEGIN 
    ROLLBACK 
END 
ELSE 
BEGIN 
    COMMIT 
END 

上面應該在SQL Server中工作,但我需要這個工作對MySQL數據庫。編輯: 對不起,有超過1條語句可以執行。是的,我知道不需要在事務中包裝單個查詢。

回答

0

我不認爲這是必要的,因爲存在隱式提交/回滾的概念。

MySQL docs

默認情況下,MySQL的啓動會話 與 自動提交模式下啓用每個新的連接,因此MySQL確實 如果 該聲明沒有返回一個 每個SQL語句之後提交錯誤。如果語句返回 錯誤,則提交或回滾行爲 取決於錯誤。見 13.6.13,「InnoDB錯誤處理」。

+0

儘管ROLLBACK還會回滾任何外部嵌套事務(至少在MSSQL中)。我認爲OP是在MSSQL中相當於@@ ERROR的MySQL檢測方法之後的,這可能只是一個Noddy示例 – Kristen 2009-02-16 09:08:20

+1

我將解釋Assaf的說法:作爲MSSQL開發人員,將MySQL視爲具有SET XACT_ABORT默認開啓。直到最近我還不熟悉這個設置。看看這個網站: http://doc.ddart.net/mssql/sql70/set-set_40.htm – DJTripleThreat 2009-06-13 06:16:17

+0

對於任何需要它的人來說,文檔已經移到這裏https://dev.mysql.com/doc/ refman/5.7/en/innodb-error-handling.html – 2017-07-07 15:04:48

0
BEGIN; 
UPDATE foo SET bar = 3; 
UPDATE bar SET thing = 5; 
COMMIT; 

如果發生錯誤,則整個事務將被自動回滾。如果應用程序中的某些內容指示需要回滾,則只需執行ROLLBACK即可。


有可能在MySQL中的過程或複合語句中顯式處理錯誤,但我不會推薦沿着這條路線走。請參閱how-to articledocs for DECLARE HANDLER。您還需要find the specific error code you want to handle,或者您可以使用一般的SQLEXCEPTION條件。您還需要查看compound statementsdefining stored programs

無論如何,基於文檔,你可以做類似於下面的查詢,但它實際上不會做任何不同於我上面的回答。它也會讓你非常奇怪看起來使用MySQL的任何人(包括我自己)。

BEGIN 
    DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 
    START TRANSACTION; 
    UPDATE foo SET bar = 3; 
    UPDATE bar SET thing = 5; 
    COMMIT; 
END; 

老答案:

如果你執行一個查詢,這是沒有意義的。只需執行查詢;如果發生錯誤,則不會發生任何事情 - 您的交易將自動回滾。

原因是,默認情況下,所有單個查詢都被封裝在一個名爲「autocommit」模式的「隱藏」事務中。典型的選擇是明確使用交易 - 一旦你執行「BEGIN」,你已經開始交易。一旦你COMMIT或ROLLBACK你會回到自動提交模式。

因此,在MySQL中使用事務的唯一原因是如果您希望在發生錯誤(或其他外部事件)時回滾到特定狀態。在MySQL中,如果發生錯誤,事務總是被中止。

最後,可以完全關閉此行爲,然後您必須始終顯式使用事務。我相信「BEGIN」隱含於您上次提交或回滾時,但您必須COMMIT或ROLLBACK您運行的任何查詢。請參閱The InnoDB Transaction Model以獲取更多信息。

1
CREATE PROCEDURE prc_test() 
BEGIN 
    DECLARE EXIT HANDLER FOR SQLEXCEPTION 
    BEGIN 
    ROLLBACK; 
    END; 
    START TRANSACTION; 
    INSERT 
    INTO t_test VALUES ('test', 'test'); 
    INSERT 
    INTO no_such_table 
    VALUES ('no'); 
    COMMIT; 
END; 

CALL prc_test(); 

SELECT * 
FROM t_test; 

0 rows fetched. 
相關問題