2010-11-18 2 views
3

Я создаю скрипт обновления MySQL, который позволит мне объединить все мои изменения sql в несколько баз данных, используя временную метку, чтобы определить, какие изменения уже были обновлены.MySQL IF Statement - скрипт с ошибкой

Я установил @cv в текущую версию базы данных. Проблема возникает в if statement. То, что когда-либо я меняю утверждение IF, приводит к падению.

SET @cv = (SELECT `value` FROM `configs` WHERE `name` = 'cvDate'); 

IF @cv <= STR_TO_DATE("2010/11/10 12:15:00") THEN 
    ALTER TABLE `feeds` ADD `tone` VARCHAR(255) NOT NULL AFTER `type` , 
    ADD `authority` DECIMAL(2, 1) NOT NULL DEFAULT '0.0' AFTER `tone`; 
END IF; 

UPDATE `configs` SET `value` = NOW() WHERE `name` = "cvDate"; 

Ошибка я получаю:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF @cv <= STR_TO_DATE("2010/11/10 12:15:00") THEN ALTER TABLE `feeds` ADD `to' at line 1 

Любая помощь будет принята с благодарностью.

+0

Является ли @cv только одним результатом или это «результат набора», я имею в виду, даже если вы просто выбираете одну строку и один элемент, возможно, @cv становится целым результатом, а не сопоставимым значением? Havn't сделал это, так что я просто мозговой штурм – Tobias

+0

Возможно ли, что второе предложение в таблице Alter не может быть проверено, потому что столбец «type» еще не существует? Альтернативно, что произойдет, если вы удалите предложение Alter Table, но оставите IF? –

ответ

3

Проблема заключается в том, что конструкция потока IF управления работает только в хранимых процедурах (так же, как и все другие Flow Control Constructs ... Так что вам нужно, чтобы определить процедуру делать то, что вы просите ...

Так вот, как определить процедуру выборки, чтобы делать то, что вы хотите:

DELIMITER // 
CREATE PROCEDURE myProcedure() 
BEGIN 
    SET @cv = (SELECT `value` FROM `configs` WHERE `name` = 'cvDate'); 

    IF @cv <= STR_TO_DATE("2010/11/10 12:15:00") THEN 
     ALTER TABLE `feeds` ADD `tone` VARCHAR(255) NOT NULL AFTER `type` , 
      ADD `authority` DECIMAL(2, 1) NOT NULL DEFAULT '0.0' AFTER `tone`; 
    END IF; 

    UPDATE `configs` SET `value` = NOW() WHERE `name` = "cvDate"; 
END// 
DELIMITER ; 

это создаст его, а затем запустить его, просто сделать:

CALL myProcedure(); 

См. the docs для получения дополнительной информации.

Вы даже можете заставить его принимать параметры, поэтому вам не нужно жестко кодировать все. Но я не уверен, как вы это сделаете, основываясь на том, что вы предоставили (я не уверен, что именно вы пытаетесь выполнить) ...

Если вы хотите, чтобы это сделало заявление sql как параметр (с использованием Prepared Statements):

DELIMITER // 
CREATE PROCEDURE myInputProcedure(IN updateDate DATETIME, IN sql TEXT) 
BEGIN 
    SET @cv = (SELECT `value` FROM `configs` WHERE `name` = 'cvDate'); 

    IF @cv <= updateDate THEN 
     PREPARE stmt1 FROM sql; 
     EXECUTE stmt1; 
    END IF; 

    UPDATE `configs` SET `value` = NOW() WHERE `name` = "cvDate"; 
END// 
DELIMITER ; 

Тогда просто называют это так:

@sql = 'ALTER TABLE `feeds` ADD `tone` VARCHAR(255) NOT NULL AFTER `type` , 
      ADD `authority` DECIMAL(2, 1) NOT NULL DEFAULT '0.0' AFTER `tone`;'; 
@date = STR_TO_DATE("2010/11/10 12:15:00"); 
CALL myInputProcedure(@date, @sql); 

(Обратите внимание, что я добавил @sql и @date для удобства чтения, а не потому, что они необходимы) ...

+0

Уход за разъяснением -1? – ircmaxell

+0

Я сделал +1, не уверен, кто сделал минус -1. Не могли бы вы дать OP очень простой пример хранимой процедуры? – Lizard

+0

Nice очень полезно! – Lizard

-2

Просто попробуйте это.

Вместо этого:

SET @cv = (SELECT `value` FROM `configs` WHERE `name` = 'cvDat'); 

Сделать это следующим образом:

SELECT @cv = `value` FROM `configs` WHERE `name` = 'cvDat'; 

Не уверен, что для MySql, но это то, что я делаю в MS SQL.

+0

Op говорит, что проблема связана с оператором IF – Lizard

+0

MySQL полностью поддерживает синтаксис ['SET'] (http://dev.mysql.com/doc/refman/5.1/en/set-option.html), как долго так как выбор только возвращает 1 строку ... – ircmaxell

0

Вы можете использовать конструкции управления потоком только в рамках хранимых процедур или функций. proof link

+0

+1 для отмены -1 (поскольку с предоставленной информацией он кажется ответом) ... – ircmaxell