2012-01-28 145 views
5

Tengo una función que actualmente uso en PHP que compila una dirección postal de campos separados pero toma en cuenta diferentes formatos utilizado en diferentes regiones. Estoy tratando de replicar esto como una función almacenada de MySQL. Me doy cuenta de que a menudo es más rápido hacer este tipo de cosas en código que en la base de datos, pero nuestra intranet permite a las personas ingresar comandos raw MySQL SELECT en modo de solo lectura para que puedan construir búsquedas avanzadas y guardar las consultas. Esta función en particular se usará para que los usuarios puedan dar salida a sus resultados de consulta de búsqueda avanzada a un diseño de etiqueta.Función almacenada de MySQL con IF anidado ... END IF, error de sintaxis, sintaxis correcta para usar cerca de '

Cuando intento y almacenar la función usando phpMyAdmin 3.4.9 (la última estable) me sale el siguiente error:

#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 

también instalado la última MySQL Workbench y sale el mismo error, pero también se resalte una "Error de sintaxis SQL cerca de 'END'", por lo que no es solo un error en phpMyAdmin (aunque podría ser un error tanto en phpMyAdmin como en MySQL Workbench).

Aquí está la consulta de función:

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;;

Línea 51 está cerca del final si, el retorno y END cláusulas pero no puede detectar nada de malo.

¿Alguien puede ver qué está causando este problema tanto en MySQL Workbench como en phpMyAdmin?
Una vez que tengo la función almacenada, puedo probarla y ajustar la lógica.

Además, si hay algo en la función que pueda simplificarse, hágamelo saber. No hay muchos ejemplos por ahí, así que he parcheado esto de alguna manera.

Respuesta

7

Ok voy a responder a mi propia pregunta. Gracias a Yahia volví a mirar mi sintaxis de declaración IF.
¡Resulta que arruiné la consulta!

Tengo 2 ELSE IF cláusulas arriba.
La sintaxis correcta de acuerdo a http://dev.mysql.com/doc/refman/5.0/en/if.html es en realidad ELSEIF
acabo de asumir que debido a END IF que también debe ser ELSE IF con un espacio, sin tener que asegurarse de la documentación.

Así que MySQL interpretó correctamente el ELSE IF como ELSE luego el inicio de otro IF anidado, en lugar de otra rama del mismo nivel.

La consulta anterior funciona perfectamente en phpMyAdmin una vez que corrige las IFs ELSE, pero tengo que hacer algunos ajustes a la lógica.

Así que toda mi culpa y RTM!

2

se echa en falta un END IF; - cambiar las últimas líneas a:

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;; 
+0

No tengo suerte, me temo :( – batfastad

+0

@batfastad That 'END IF;' quizás no sea lo único que falta ... pero no tengo MySQL instalado para verificarlo ... – Yahia

+0

Lo suficiente, yo Verificará rápidamente que mis anidamientos coincidan. Saludos :) – batfastad

5

Otra solución. Pruebe con una función:

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 ; 

Saludos.

Cuestiones relacionadas