如何在PostgreSQL中测试运行UPDATE语句?

114

我该如何测试一个更新语句,例如检查它是否有效,是否会实际更新行等?

有没有一种简单模拟的方法呢?

7个回答

188

使用事务将您的更新语句和选择查询(用于测试更新)包装起来,然后始终回滚。

示例:

BEGIN;

UPDATE accounts SET balance = balance - 100.00
    WHERE name = 'Alice';

SELECT balance FROM accounts WHERE name = 'Alice';

ROLLBACK; -- << Important! Un-does your UPDATE statement above!

一次事务通常以提交结束,但由于您只是在测试,不希望更改永久生效,因此您只需要回滚操作。


你为什么要进行更新,难道你不相信psql吗?:) - Давид Шико
这个 TRANSACTION 适用于所有的 SQL 版本吗? - Robin
@ДавидШико 因为我没有写这个声明。 - RonJohn

58

将它包装在一个事务中,在最后使用SELECT测试结果并回滚。

BEGIN;

UPDATE ...;

SELECT ...;

ROLLBACK;

8
在UPDATE查询中使用RETURNING可以省略SELECT查询。 - Frank Heikens
7
如果您决定保留更改,请使用COMMIT而不是ROLLBACK - n.st

31
在你的SQL UPDATE 命令前加上 EXPLAIN [ref],它将不会执行实际的更新。例如:
EXPLAIN UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Alice';

很不幸,它不会(总是)告诉你将要更新的行数,而是告诉你有多少行与WHERE子句匹配。在上面的例子中,这两个数字是相同的。
你可以参考Paul Sasik的回滚方法。

3
它会告诉你有多少行将受到你的命令的影响 - 我不认为这是正确的;它只会告诉你它将扫描多少行。 - jameshfisher

5
你可以在SQL Fiddle上建立样本数据库,然后在那里尝试更新语句。
完全透露:我是sqlfiddle.com的作者。

1
SQL Fiddle是一个很好的学习工具,但是在那里设置一个多表数据库来测试查询并不是最佳选择。还是要赞一下这个网站! - seniorpreacher
SQL Fiddle是一个很棒的学习工具,但是为了测试一个查询而在那里设置一个多表数据库并不是最佳选择。还是要赞扬这个网站! - seniorpreacher

1

使用Postgres,您可以使用UPDATE子句RETURNING来显示已修改的行。

-- example data
CREATE TABLE data(id int, text text);
INSERT INTO DATA VALUES(1,'aaa'),(2,'bbb'),(3,'ccc'),(4,'ddd');

-- original data
SELECT * from data;

-- dry-run update
BEGIN;

UPDATE
  data
SET
  text = 'modified'
WHERE
  id > 2
RETURNING
  id, text;

ROLLBACK;

-- data after dry-run update
SELECT * from data;

1
回滚是避免提交任何更改的操作。 - adrianlzt

0

考虑到这个简单的更新:

UPDATE Products
   SET price_including_vat = price * 1.05
 WHERE product_type = 'Food';

我会使用类似这样的方式进行测试:
 SELECT price_including_vat AS price_including_vat__before, 
        price * 1.05 AS price_including_vat__after, 
        *
   FROM Products
 WHERE product_type = 'Food';

实际上,我可能会动动脑筋,更像这样进行分析:

WITH updated AS 
   (
    SELECT price_including_vat AS price_including_vat__before, 
           price * 1.05 AS price_including_vat__after, 
           *
      FROM Products
    WHERE product_type = 'Food'
   )
SELECT * 
  FROM updated
 WHERE price_including_vat__before = price_including_vat__after;

0

首先使用SELECT语句运行相同的检查:SELECT返回的行将是UPDATE修改的行。


2
仅使用简单的SELECT语句是不够的。可能存在外键约束、CHECK约束等,这些约束条件无法通过简单的SELECT语句检测到。SELECT语句只会测试WHERE子句,但即使SELECT成功,UPDATE操作也可能失败。 - mu is too short

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接