在某些情况下,在生产环境中运行UPDATE语句可以节省一天的时间。但是,更新失败可能比最初的问题更严重。
除了不使用测试数据库,还有哪些选项可以告诉您更新语句在运行前将要执行的操作?
在某些情况下,在生产环境中运行UPDATE语句可以节省一天的时间。但是,更新失败可能比最初的问题更严重。
除了不使用测试数据库,还有哪些选项可以告诉您更新语句在运行前将要执行的操作?
Answers:
除了使用Imad所说的事务(无论如何应该强制执行)之外,您还可以通过使用与UPDATE相同的WHERE子句运行select来进行完整性检查。
因此,如果您的UPDATE是
UPDATE foo
SET bar = 42
WHERE col1 = 1
AND col2 = 'foobar';
下面将向您显示将更新哪些行:
SELECT *
FROM foo
WHERE col1 = 1
AND col2 = 'foobar';
FOREIGN KEY UPDATE CASCADE
的SQL失败了
交易呢?它们具有回滚功能。
@请参阅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 fe中,您将编写类似的内容(也许更简洁一些,但是想快速回答;-)):
$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;
但是我建议使用您喜欢的编程语言中可用的语言包装器。
自动提交关闭...
的MySQL
set autocommit=0;
它为当前会话设置自动取消。
您可以执行语句,查看其更改,然后在错误的情况下回滚,或者在期望的情况下进行提交!
编辑:使用事务而不是运行选择查询的好处是您可以更轻松地检查结果集。
我知道这是其他答案的重复,但是它有情感上的支持,可以采取额外的步骤来测试更新:D
对于测试更新,#是您的朋友。
如果您有类似以下内容的更新语句:
UPDATE
wp_history
SET history_by="admin"
WHERE
history_ip LIKE '123%'
您对UPDATE进行哈希处理并开始进行测试,然后将其哈希回去:
SELECT * FROM
#UPDATE
wp_history
#SET history_by="admin"
WHERE
history_ip LIKE '123%'
它适用于简单的语句。
另一个实际上强制性的解决方案是,每当在生产表上使用update时,就获得一个副本(备份副本)。Phpmyadmin>操作>复制:table_yearmonthday。<= 100M的表只需要几秒钟。
在您要测试的这些情况下,最好只关注当前列值以及即将更新的值列值。
请查看以下为更新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
这样,我们可以清楚地将现有值与新值进行比较。
做一个SELECT
吧,
就像你有
UPDATE users SET id=0 WHERE name='jan'
转换成
SELECT * FROM users WHERE name='jan'