Navicat 博客

如何在执行前测试 Insert 和 Update 语句 2022 年 6 月 2 日,由 Robert Gravelle 撰写

在某些情况下,在生产环境中运行认真草拟的 UPDATE 语句可以解除危机。其他时候,一个拙劣的 UPDATE 可能会比最初的问题造成更多的危害。就像你总是可以在开发或测试数据库上执行数据操作语言(Data Manipulation Language,DML)语句,但由于数据的差异,这种方法最多只能判断语句对生产数据的影响。

那么,在运行 INSERT、UPDATE 或 DELETE 语句之前,有哪些选项可以准确预测其结果对生产数据的影响?至少部分取决于数据库供应商和产品。还有一些解决方案得到了广泛的支持。我们将在本文中看看这两个选项。

语法检查

测试语句的过程可以分为两个阶段。首先是验证语句在语法上是否有效(即它能执行)。下一步是确定它是否能产生你想要的结果。

验证语法的一种方法是向数据库(DB)询问查询计划。这能告诉你两件事:

  • 查询是否有语法错误;如果是这样,查询计划命令本身将会失败。
  • 数据库计划如何执行查询,例如将使用什么索引。

在大部分关系数据库中,查询计划命令是“explain”或“describe”,如下所示:

explain update ...;

在 Navicat 的数据库管理和开发工具中,单击按钮即可运行 EXPLAIN 命令。如果语句失败,你将收到类似以下的错误消息:

explain (99K)

否则,查询计划将以表格形式显示:

explain_success (65K)

语句测试

你可以分析语句以查看它在语法上是否有效,但这并不意味着它会产生正确的结果。若要查看查询实际上会做什么,你有几个选项。

关闭自动提交

大多数关系数据库都提供了一种禁用自动提交(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 天试用版。

Navicat 文章
频道条目
分享
文章归档