MySQL: операторы IF / THEN в хранимых процедурах - PullRequest
11 голосов
/ 12 мая 2011

Я пишу хранимую процедуру, которая использует несколько операторов IF / THEN, которые также должны выполнять несколько запросов, если они оцениваются как true. Проблема в том, что я не могу найти никаких примеров соответствующего синтаксиса. Из справочника по MySQL кажется, что у меня может быть несколько запросов в "Statement_list", но пока я не могу заставить его работать.

Вот что я пытаюсь сделать:

SET agency = 
  COALESCE((SELECT org_agency_o_id 
            FROM orgs_agencies 
            WHERE org_agency_code = maj_agency_cat)
              ,(SELECT min(org_id) 
                FROM orgs     
                WHERE org_name LIKE CONCAT('U.S.',SUBSTRING(maj_agency_cat,5)))) 

IF agency IS NULL THEN 
  -- execute multiple queries   
  INSERT INTO orgs (org_name
                   ,org_name_length
                   ,org_type
                   ,org_sub_types) 
  VALUES (CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5))
         ,LENGTH(CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5)))
         ,'org','Org,GovernmentEntity,Federal,Agency');

SET agency = LAST_INSERT_ID();
END IF;

Ошибка:

У вас ошибка в синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, для правильного синтаксиса, чтобы использовать около 'IF agency IS NULL THEN INSERT INTO orgs (org_name,org_name_length,org_type,' в строке 53

Есть идеи? Я знаю, что это должно быть что-то простое, поэтому я был бы очень признателен за любой вклад.

Ответы [ 2 ]

21 голосов
/ 13 мая 2011

Насколько я понимаю, у вас есть несколько проблем:

  1. Как указывал Дэвид, каждое утверждение должно заканчиваться ;
  2. Если высделайте SELECT, лучше убедитесь, что он может выбрать только одно значение, выполнив LIMIT 1;Если у вас есть агрегатная функция, такая как min(), то может появиться только одно значение.
  3. Если вы пишете процедуру с использованием синтаксиса CREATE PROCEDURE ..., не забудьте установить DELIMITER $$ перед CREATE PROCEDURE ... END $$ body и DELIMITER ; after.
  4. Если в вашем блоке IF THEN ... END IF есть несколько операторов, рекомендуется поместить их в блок BEGIN ... END;.
  5. Если выиметь возвращаемое значение, например, как агентство, почему бы не сделать его FUNCTION name (arg1: INTEGER) RETURNS INTEGER вместо PROCEDURE name (IN arg1 INTEGER, OUT agency INTEGER).Функция намного более универсальна.
DELIMITER $$
CREATE PROCEDURE name(arg1 INTEGER, arg2 INTEGER, ...)
BEGIN

  SELECT SET agency = 
    COALESCE((SELECT org_agency_o_id 
            FROM orgs_agencies 
            WHERE org_agency_code = maj_agency_cat) LIMIT 1,
    (SELECT min(org_id) FROM orgs     
    WHERE org_name LIKE CONCAT('U.S.',SUBSTRING(maj_agency_cat,5)))); 

  IF agency IS NULL THEN BEGIN
    -- execute multiple queries   
    INSERT INTO orgs (org_name
                     ,org_name_length
                     ,org_type
                     ,org_sub_types) 
    VALUES (CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5))
           ,LENGTH(CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5)))
           ,'org','Org,GovernmentEntity,Federal,Agency');

    SET agency = LAST_INSERT_ID();
  END; END IF;
END $$

DELIMITER ;
2 голосов
/ 13 мая 2011

Нет точки с запятой после вашего первого оператора SET.

...