2011-05-12 20 views
11

Estoy escribiendo un procedimiento almacenado que usa múltiples instrucciones IF/THEN que también necesitan ejecutar múltiples consultas si se evalúan como verdaderas. El problema es que parece que no puedo encontrar ningún ejemplo de la sintaxis adecuada. Desde el MySQL dev handbook, parece que podría tener múltiples consultas en la "lista_de_claves", pero hasta ahora no puedo hacer que funcione.MySQL: instrucciones IF/THEN en procedimientos almacenados

Aquí es lo que estoy tratando de hacer:

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; 

El error:

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 agency IS NULL THEN INSERT INTO orgs (org_name,org_name_length,org_type,' at line 53

¿Alguna idea? Sé que tiene que ser algo simple, por lo que agradecería mucho las aportaciones de cualquier persona.

Respuesta

21

Usted tiene algunos problemas por lo que yo puedo ver:

  1. Como David señaló, todos y cada afirmación debe ser terminada por un ;
  2. Si lo hace un SELECT, mejor asegurarse solo puede seleccionar un valor haciendo LIMIT 1; Si tiene una función agregada como min(), solo puede salir un valor.
  3. Si escribe el procedimiento utilizando la sintaxis CREATE PROCEDURE ..., no olvide establecer DELIMITER $$ antes del cuerpo CREATE PROCEDURE ... END $$ y DELIMITER ; después.
  4. Si tiene varias instrucciones dentro de su bloque IF THEN ... END IF, es una buena idea colocarlas dentro de un bloque BEGIN ... END;.
  5. Si tiene un valor de retorno, como agencia aquí, ¿por qué no hacerlo FUNCTION name (arg1: INTEGER) RETURNS INTEGER en lugar de PROCEDURE name (IN arg1 INTEGER, OUT agency INTEGER). La función es mucho más versátil.
 
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 ; 
+0

fantástico, gracias! – tchaymore

2

No hay punto y coma después de su primera instrucción SET.

Cuestiones relacionadas