在某些情況下,在生產環境中執行認真草擬的 UPDATE 陳述式可以解除危機。其他時候,一個拙劣的 UPDATE 可能會比最初的問題造成更多的危害。就像你總是可以在開發或測試資料庫上執行資料調處語言(Data Manipulation Language,DML)陳述式,但由於資料的差異,這種方法最多只能判斷陳述式對生產資料的影響。
那麼,在執行 INSERT、UPDATE 或 DELETE 陳述式之前,有哪些選項可以準確預測其結果對生產資料的影響呢?至少部分取決於資料庫供應商和產品。還有一些解決方案得到了廣泛的支持。我們將在本文中看看這兩個選項。
語法檢查
測試陳述式的程序可以分為兩個階段。第一步是驗證陳述式在語法上是否有效(即它能執行)。下一步是確定它是能產生你想要的結果。
驗證語法的一種方法是向資料庫(DB)詢問查詢計劃。這能告訴你兩件事:
- 查詢是否有語法錯誤;如果是這樣,查詢計劃命令本身將會失敗。
- 資料庫計劃如何執行查詢,例如將使用哪些索引。
在大部分關聯式資料庫中,查詢計劃命令是「explain」或「describe」,例如:
explain update ...;
在 Navicat 的資料庫管理和開發工具中,按一下按鈕即可執行 EXPLAIN 命令。如果陳述式失敗,你將收到類似以下的錯誤訊息:
否則,査詢計劃將以表格形式顯示:
陳述式測試
你可以剖析陳述式以查看它在語法上是否有效,但這並不意味著它會產生正確的結果。若要查看查詢實際上會做什麼,你有幾個選項。
關閉自動認可
大多數關聯式資料庫都提供了一種停用自動認可(autocommit)模式的方法,因此你必須發出 COMMIT 陳述式來將變更儲存至磁碟,或者發出 ROLLBACK 以忽略變更。
在 MySQL 中,停用自動認可模式的命令是:
SET autocommit=0 Or SET autocommit = OFF
In SQL Server, the command is:
SET IMPLICIT_TRANSACTIONS OFF
關閉自動認可後,你現在可以在交易中執行陳述式來嘗試一下:
-- 1. start a new transaction START TRANSACTION; -- 2. insert a new order for customer 145 INSERT INTO orders(orderNumber, orderDate, requiredDate, shippedDate, status, customerNumber) VALUES(@orderNumber, '2005-05-31', '2005-06-10', '2005-06-11', 'In Process', 145); -- 3. then, after evaluating the results, -- rollback the changes ROLLBACK;
這將使資料庫保持與執行陳述式之前完全相同的狀態。
將陳述式轉換為 SELECT
測試 DML 陳述式的一種低技術方法是將它們轉換為 SELECT。只要你不期望它們擷取整個資料庫,那麼以 SELECT 執行它們是種很好的方法,可以準確查看哪些記錄將受到影響。你需要做的就是用 SELECT 取代動作詞語:
INSERT INTO orders... BECOMES SELECT * FROM ORDERS...
總結
沒有什麼比在生產環境中執行 DML 陳述式更可怕的了。值得慶幸的是,有一些方法可以將風險降到最低,這樣你就不必祈求好運到來。
如果你想試用 Navicat 16,你可以在這裡下載 14 天試用版。