Хорошо, новый ответ. Дело не в том, что щедрость делает меня более креативным, скорее я чувствую себя менее сдержанно, предлагая решение I , не считаю прямым:)
(я все еще предполагаю, что вы хотите избежать хранимых процедур любой ценой)
Решение № 1: с использованием подготовленных заявлений
Предположим, ваш сценарий обновления прост:
ALTER TABLE t ADD COLUMN c INT DEFAULT 1
Тогда как насчет этого:
SET @version := '1';
SELECT CASE val
WHEN @version THEN
'ALTER TABLE t ADD COLUMN c INT DEFAULT 1'
ELSE 'SELECT ''Wrong version. Nothing to upgrade.'''
END
INTO @stmt
FROM meta
WHERE name = 'Version';
PREPARE stmt FROM @stmt;
EXECUTE stmt;
Очевидные недостатки:
- Разбейте беспорядок и накладные расходы, поскольку вы должны написать это для каждого отдельного оператора (
PREPARE
не может пакетировать несколько операторов)
- дополнительное раздражение, потому что вы должны записывать каждое утверждение из вашего скрипта обновления в виде строки ... yuck
- не все операторы могут быть написаны и выполнены с
PREPARE
Решение № 2: один подготовленный оператор, чтобы УБИТЬ соединение
Вы уже указали, что вам не нравится решение, которое вы тоже связали ... это из-за оператора KILL
или из-за сохраненной функции? Если это из-за сохраненной функции, вы можете обойти это:
SET @version := '1';
SELECT CASE val
WHEN @version THEN 'SELECT ''Performing upgrade...'''
ELSE CONCAT('KILL CONNECTION', connection_id())
END
INTO @stmt
FROM meta
WHERE name = 'Version';
PREPARE stmt FROM @stmt;
EXECUTE stmt; -- connection is killed if the version is not correct.
-- remainder of the upgrade script goes here...
mysql
необходимо запустить с параметром --skip-reconnect
, чтобы гарантировать, что никакие операторы не могут быть выполнены, если соединение разорвано
Я попытался обойти этот недостаток и использовал PREPARE
для других вещей, которые блокировали бы текущее соединение, таких как удаление пользователя и отзыв его привилегий. К сожалению, это не работает как задумано (нет, также не после FLUSH PRIVILEGES
)
Решение № 3: использовать прокси-сервер mysql для перехвата
Еще одно решение: использовать прокси. С помощью прокси-сервера mysql (см .: http://forge.mysql.com/wiki/MySQL_Proxy), вы можете написать собственный сценарий перехвата в lua, который интерпретирует ваши пользовательские команды. С его помощью вы можете добавить необходимые управляющие структуры. Недостаток: теперь вам нужно создать свой собственный мини-язык, и научись Луа интерпретировать это:)