如何在运行之前测试SQL Update语句?

时间:2012-06-13 08:55:39

标签: mysql sql database testing myisam

在某些情况下,在生产中运行UPDATE语句可以节省一天。然而,borked更新可能比最初的问题更糟糕。

如果没有使用测试数据库,在运行之前有什么选项可以告诉更新语句将执行什么操作?

9 个答案:

答案 0 :(得分:51)

交易怎么样?他们有ROLLBACK-Feature。

@see https://dev.mysql.com/doc/refman/5.0/en/commit.html

例如:

START TRANSACTION;
SELECT * FROM nicetable WHERE somthing=1;
UPDATE nicetable SET nicefield='VALUE' WHERE somthing=1;
SELECT * FROM nicetable WHERE somthing=1; #check

COMMIT;
# or if you want to reset changes 
ROLLBACK;

SELECT * FROM nicetable WHERE somthing=1; #should be the old value

在下面的@rickozoe上回答问题:

一般来说,这些行不会被执行一次。在PHP中。你会写那样的东西(也许有点干净,但想快速回答;-)):

$MysqlConnection->query('START TRANSACTION;');
$erg = $MysqlConnection->query('UPDATE MyGuests SET lastname='Doe' WHERE id=2;');
if($erg)
    $MysqlConnection->query('COMMIT;');
else
    $MysqlConnection->query('ROLLBACK;');

另一种方法是使用MySQL变量(参见https://dev.mysql.com/doc/refman/5.7/en/user-variables.htm l 和 https://stackoverflow.com/a/18499823/1416909 ):

# do some stuff that should be conditionally rollbacked later on

SET @v1 := UPDATE MyGuests SET lastname='Doe' WHERE id=2;
IF(v1 < 1) THEN
    ROLLBACK;
ELSE
    COMMIT;
END IF;

但我建议使用您喜欢的编程语言中提供的语言包装器。

答案 1 :(得分:50)

自动提交OFF ...

<强>的MySQL

set autocommit=0;

它为当前会话设置自动提示。

您执行语句,查看它已更改的内容,然后如果错误则回滚,或者如果它符合您的预期则进行回滚!

编辑:使用事务而不是运行选择查询的好处是您可以更容易地检查结果集。

答案 2 :(得分:34)

除了使用Imad所说的事务(无论如何应该是强制的)之外,你还可以通过使用与UPDATE相同的WHERE子句运行select来检查哪些行受到影响。

所以如果你更新是

UPDATE foo
  SET bar = 42
WHERE col1 = 1
  AND col2 = 'foobar';

以下将显示哪些行将更新:

SELECT *
FROM foo
WHERE col1 = 1
  AND col2 = 'foobar';

答案 3 :(得分:11)

我知道这是其他答案的重复,但它有一些情感上的支持来采取额外的步骤来测试更新:D

为了测试更新,hash#是你的朋友。

如果你有更新声明,如:

UPDATE 
wp_history
SET history_by="admin"
WHERE
history_ip LIKE '123%'

您散列UPDATE并SET出来进行测试,然后将它们哈希回来:

SELECT * FROM
#UPDATE
wp_history
#SET history_by="admin"
WHERE
history_ip LIKE '123%'

适用于简单的陈述。

每当在生产表上使用更新时,另一个实际上必须的解决方案是获取副本(备份副本)。 Phpmyadmin&gt;操作&gt; copy:table_yearmonthday。表格&lt; = 100M只需要几秒钟。

答案 4 :(得分:4)

不是一个直接的答案,但我看到很多borked prod数据情况可以通过首先输入WHERE子句来避免!有时,WHERE 1 = 0可以帮助您安全地将工作声明放在一起。并且查看估计执行计划(将估计受影响的行)可能很有用。除此之外,在你回滚的交易中,正如其他人所说的那样。

答案 5 :(得分:1)

在同一个表上运行select query,其中包含您在更新查询中应用的所有where条件。

答案 6 :(得分:0)

制作SELECT

就像你有

一样

UPDATE users SET id=0 WHERE name='jan'

将其转换为

SELECT * FROM users WHERE name='jan'

答案 7 :(得分:0)

在这些要测试的情况下,最好只关注当前列值和即将更新列值。

>

请查看以下我为更新WHMCS价格而编写的代码:

# UPDATE tblinvoiceitems AS ii

SELECT                        ###  JUST
    ii.amount AS old_value,   ###  FOR
    h.amount AS new_value     ###  TESTING
FROM tblinvoiceitems AS ii    ###  PURPOSES.

JOIN tblhosting AS h ON ii.relid = h.id
JOIN tblinvoices AS i ON ii.invoiceid = i.id

WHERE ii.amount <> h.amount   ### Show only updatable rows

# SET ii.amount = h.amount

通过这种方式,我们可以清晰地比较现有值和新值。

答案 8 :(得分:0)

另一种选择是向MySQL请求查询计划。这告诉您两件事:

  • 查询中是否有语法错误,如果这样,查询计划命令本身将失败
  • MySQL如何计划执行查询,例如它将使用什么索引

在MySQL和大多数SQL数据库中,查询计划命令为describe,因此您可以这样做:

describe update ...;