在某些情况下,在生产环境中运行认真草拟的 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
在 SQL Server 中,命令是:
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 天试用版。