2012-06-13 8 views
55

В некоторых случаях запуск инструкции UPDATE в процессе производства может сохранить день. Однако обновление borked может быть хуже, чем исходная проблема.Как проверить инструкцию SQL Update перед запуском?

Зачем использовать тестовую базу данных, каковы параметры, чтобы сказать, что будет делать инструкция по обновлению перед запуском?

ответ

24

В дополнение к использованию транзакции, о которой говорил Имад (которая обязательно должна быть обязательной), вы также можете провести проверку работоспособности, на которые влияют строки, запустив выбор с использованием того же предложения WHERE, что и UPDATE.

Так что, если вы UPDATE является

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

Ниже будет показано, какие строки будут обновлены:

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

Используя транзакции, лучше проверить данные. Предполагая, что он хочет проверить результат, я заключаю, что его утверждение более сложное, чем «SET bar = 42», поэтому в рамках его сессии он сможет сделать несколько запросов для тестирования результирующего набора данных ... –

+1

@ImadMoqaddem: Я согласен, и именно поэтому я написал «* Помимо использования транзакции, как сказал Имад *» –

+0

И если у вас есть 'FOREIGN KEY UPDATE CASCADE', ваш sql не работает – Green

40

Autocommit OFF ...

MySQL

set autocommit=0; 

Он устанавливает autommit от текущего сеанса.

Вы выполняете свое заявление, видите, что он изменил, а затем откат, если он ошибочен или совершает, если это то, что вы ожидали!

EDIT: Преимущество использования транзакций вместо запуска запроса выбора заключается в том, что вы можете легко проверить полученный набор.

+7

Просто проверьте, что ваши таблицы поддерживают транзакции ... –

+4

@dystroy: каждая разумная СУБД поддерживает транзакции. –

+3

Просто помните, чтобы совершить или отменить транзакцию быстро, или вы рискуете заблокировать другие транзакции, а в худшем случае приложите ваше приложение к остановке. Неплохая идея выполнить запрос, затем пообедать, а затем вернуться, чтобы увидеть результаты! :-) –

1

Запустите запрос выбора в той же таблице со всеми условиями where, которые применяются в запросе обновления.

0

сделать SELECT его,

, как если бы вы получили

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

преобразовать его в

SELECT * FROM users WHERE name='jan'

3

Не прямой ответ, но я видел много BORKED ситуаций прод данных, которые можно было бы избежать, введя WHERE пункт первый! Иногда WHERE 1 = 0 может помочь с безопасным размещением рабочего заявления. И может быть полезно посмотреть примерный план выполнения, который оценит затронутые строки. Помимо этого, в транзакции, которую вы откатываете назад, как говорили другие.

+1

Что случилось с 'WHERE FALSE'? – SystemParadox

+0

@SystemParadox - ничего, хотя 'WHERE 1 = 0' более портативен, если кто-то сталкивается с этим, кто работает с другой СУБД. Например, SQL Server не будет принимать 'WHERE FALSE'. –

6

Я знаю, что это повторение других ответов, но у него есть эмоциональная поддержка, чтобы взять дополнительный шаг для обновления тестирования: D

Для обновления тестирования хэш # является вашим другом.

Если у вас есть обновление заявление, как:

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

You хэш UPDATE и SET вне для тестирования, а затем хэш их обратно:

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

Это работает для простых операторов.

Дополнительным практически обязательным решением является получение копии (дублирующего дубликата) при каждом использовании обновления в производственной таблице. Phpmyadmin> операции> copy: table_yearmonthday. Это займет всего несколько секунд для таблиц < = 100M.

33

Что относительно Сделок? У них есть функция ROLLBACK.

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

Например:

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 f.e. можно было бы написать что-то вроде этого (возможно, немного чище, но хотел ответить быстро ;-)):

$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 л и 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; 

Но я бы предложил использовать языковые обертки, доступные на вашем любимом языке программирования.

+0

Хороший безопасный подход, спасибо. – input

+0

Это приведет к неожиданным результатам с вложенными транзакциями. – scones

+0

Не могли бы вы привести пример? –

Смежные вопросы