Сохраненная функция MySQL с вложенным IF... END IF, ошибка в синтаксисе, правильный синтаксис для использования рядом с ''
У меня есть функция, которую я сейчас использую в PHP, которая компилирует почтовый адрес из отдельных полей, но учитывает разные форматы, используемые в разных регионах. Я пытаюсь воспроизвести это как хранимую функцию MySQL. Я понимаю, что зачастую делать подобные вещи быстрее в коде, чем в базе данных, но наша интрасеть позволяет людям вводить необработанные команды MySQL SELECT только для чтения, чтобы они могли создавать расширенные поисковые запросы и сохранять запросы. Эта конкретная функция будет использоваться для того, чтобы пользователи могли выводить результаты своего расширенного поискового запроса в макет метки.
Когда я пытаюсь сохранить функцию с помощью phpMyAdmin 3.4.9 (последняя стабильная версия), я получаю следующую ошибку:
#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 '' at line 51
Я также установил последнюю версию MySQL Workbench и получил ту же ошибку, но также выделил "Ошибка синтаксиса SQL рядом с" END "", так что это не просто ошибка в phpMyAdmin (хотя это может быть ошибка как в phpMyAdmin, так и в MySQL Workbench).
Вот запрос функции:
DELIMITER ;;
DROP FUNCTION IF EXISTS ADDRESS_BUILD;;
CREATE FUNCTION ADDRESS_BUILD(contact VARCHAR(50), company VARCHAR(100), add1 VARCHAR(255), add2 VARCHAR(255), add3 VARCHAR(255), town_city VARCHAR(50), county_state VARCHAR(50), postcode_zip VARCHAR(50), country VARCHAR(100), `separator` VARCHAR(10), type VARCHAR(10))
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE address TEXT;
DECLARE line TEXT;
IF LENGTH(TRIM(contact))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(contact)); END IF;
IF LENGTH(TRIM(company))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(company)); END IF;
IF LENGTH(TRIM(add1))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(add1)); END IF;
IF LENGTH(TRIM(add2))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(add2)); END IF;
IF LENGTH(TRIM(add3))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(add3)); END IF;
IF country='United States of America' OR country='USA' OR country='Canada' OR country='CA' THEN
/* NORTH AMERICA, ALL ON 1 LINE */
IF LENGTH(TRIM(town_city))>0 THEN
IF type='mail' THEN SET line=CONCAT_WS('', TRIM(town_city), ' ');
ELSE SET line=CONCAT_WS('', line, TRIM(town_city), ', ');
END IF;
END IF;
IF LENGTH(TRIM(county_state))>0 THEN
IF type='mail' THEN SET line=CONCAT_WS('', line, TRIM(county_state), ' ');
ELSE SET line=CONCAT_WS('', line, TRIM(county_state), ' ');
END IF;
END IF;
IF LENGTH(TRIM(postcode_zip))>0 THEN SET line=CONCAT_WS('', line, TRIM(postcode_zip)); END IF;
SET address=CONCAT_WS(`separator`, address, TRIM(line));
ELSE IF country='United Kingdom' OR country='UK' THEN
/* UK, ASCENDING LOCALITY SEPARATE LINES */
IF LENGTH(TRIM(town_city))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(town_city)); END IF;
IF LENGTH(TRIM(county_state))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(county_state)); END IF;
IF LENGTH(TRIM(postcode_zip))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(postcode_zip)); END IF;
ELSE
/* EUROPE EVERYWHERE ELSE, ALL ON 1 LINE POSTCODE FIRST */
IF LENGTH(TRIM(postcode_zip))>0 THEN SET line=CONCAT_WS('', line, TRIM(postcode_zip)); END IF;
IF LENGTH(TRIM(town_city))>0 THEN SET line=CONCAT_WS('', line, ' ', TRIM(town_city)); END IF;
IF LENGTH(TRIM(county_state))>0 THEN SET line=CONCAT_WS('', line, ' ', TRIM(county_state)); END IF;
IF LENGTH(TRIM(line))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(line)); END IF;
END IF;
IF country='United States of America' THEN SET address=CONCAT_WS(`separator`, address, 'USA');
ELSE IF LENGTH(TRIM(country))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(country));
END IF;
RETURN address;
END;;
Строка 51 находится рядом с предложениями END IF, RETURN и END, но я не вижу в этом ничего плохого.
Кто-нибудь может увидеть, что вызывает эту проблему в MySQL Workbench и phpMyAdmin?
После того, как функция сохранена, я могу проверить ее и настроить логику.
Также, если в функции есть что-то, что можно упростить, дайте мне знать. Там не так много примеров, поэтому я несколько исправил это.
3 ответа
Хорошо, я собираюсь ответить на мой собственный вопрос. Благодаря Yahia я еще раз взглянул на синтаксис оператора IF.
Оказывается, я облажался запрос!
У меня 2 ELSE IF
пункты выше.
Правильный синтаксис в соответствии с http://dev.mysql.com/doc/refman/5.0/en/if.html на самом деле ELSEIF
Я просто предположил, что из-за END IF
что это также должно быть ELSE IF
с пробелом, фактически не убедившись в документах.
Таким образом, MySQL вполне правильно интерпретировал ELSE IF как ELSE, а затем начало другого вложенного IF, а не другой ветви того же уровня.
Приведенный выше запрос прекрасно работает в phpMyAdmin, как только вы исправите ELSE IF, но у меня есть несколько настроек для логики.
Так что во всем виноват и РТМ!
Другое решение. Попробуйте с функцией:
DROP FUNCTION IF EXISTS test;
DELIMITER $$
CREATE FUNCTION test(name VARCHAR(255), id INT) RETURNS INT
BEGIN
DECLARE var_resp INT DEFAULT 0;
IF (LENGTH(TRIM(name)) > 0) THEN
UPDATE mytableset IDName= name WHERE mytable.ID = id
SET var_resp = 1;
END IF;
RETURN var_resp;
END $$
DELIMITER ;
С уважением.
Вам не хватает END IF;
- измените последние строки на:
IF country='United States of America' THEN SET address=CONCAT_WS(`separator`, address, 'USA');
ELSE IF LENGTH(TRIM(country))>0 THEN SET address=CONCAT_WS(`separator`, address, TRIM(country));
END IF;
END IF;
RETURN address;
END;;