在某些情况下,在生产中运行UPDATE语句可以节省一天。然而,borked更新可能比最初的问题更糟糕。
如果没有使用测试数据库,在运行之前有什么选项可以告诉更新语句将执行什么操作?
答案 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
一般来说,这些行不会被执行一次。在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和大多数SQL数据库中,查询计划命令为describe
,因此您可以这样做:
describe update ...;