2012-01-28 14 views
5

Mam funkcję, której aktualnie używam w PHP, która kompiluje adres mailingowy z oddzielnych pól, ale bierze pod uwagę różne formaty stosowane w różnych regionach. Próbuję replikować to jako funkcja przechowywana MySQL. Zdaję sobie sprawę, że często dzieje się tak szybciej w kodzie niż w bazie danych, ale nasz intranet ma możliwość wprowadzania surowych poleceń SELECT MySQL w trybie tylko do odczytu, dzięki czemu mogą tworzyć zaawansowane wyszukiwania i zapisywać zapytania. Ta konkretna funkcja będzie używana, aby użytkownicy mogli wysyłać wyniki wyszukiwania zaawansowanego do układu etykiety.Funkcja zapisana w MySQL z zagnieżdżonym IF ... END IF, błąd w składni, prawidłowa składnia do użycia w pobliżu ''

Gdy próbuję i przechowywać funkcję za pomocą phpMyAdmin 3.4.9 (najnowsza stabilna) pojawia się następujący błąd:

#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 

ja również zainstalowany najnowszy MySQL Workbench i uzyskać ten sam błąd, ale również to podświetlone "Błąd składni SQL w pobliżu" END ", więc nie jest to tylko błąd w phpMyAdminie (choć może to być błąd zarówno w phpMyAdmin, jak i MySQL Workbench).

Oto zapytanie funkcja:

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

Linia 51 zbliża się do końca, jeżeli klauzul wrócić i koniec, ale nie mogę nic złego w tym miejscu.

Czy ktoś może zobaczyć, co powoduje ten problem w obu MySQL Workbench i phpMyAdmin?
Po zapisaniu funkcji mogę ją przetestować i poprawić logikę.

Również jeśli istnieją jakieś funkcje, które można usprawnić, daj mi znać. Nie ma zbyt wielu przykładów, więc trochę to załatałem.

Odpowiedz

7

Ok mam zamiar odpowiedzieć na moje własne pytanie. Dzięki Yahia przyjrzałem się kolejnej składni instrukcji IF.
Okazuje się, że spieprzyłem zapytanie!

Mam powyżej 2 ELSE IF.
Prawidłowa składnia według http://dev.mysql.com/doc/refman/5.0/en/if.html jest rzeczywiście ELSEIF
po prostu założyć, że z powodu END IF, że powinna ona być również ELSE IF z miejsca, bez faktycznie upewniając z docs.

W związku z tym MySQL poprawnie interpretował ELSE IF jako ELSE, a następnie start innego zagnieżdżonego IF, zamiast innej gałęzi tego samego poziomu.

Powyższe zapytanie działa idealnie w phpMyAdmin po poprawieniu ELSE IFs, ale mam kilka poprawek do logiki.

Tak więc wszystkie moje winy i RTM!

2

jesteś brakuje END IF; - zmień ostatnie wiersze:

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

Bez powodzenia Obawiam się :( – batfastad

+0

@batfastad Że 'END IF;' nie jest może jedyną rzeczą, której brakuje ... ale nie mam zainstalowanego MySQL, aby to sprawdzić ... – Yahia

+0

Dość, ja "Szybko sprawdzę, czy moje gniazda pasują do siebie. – batfastad

5

Inne rozwiązanie. Wypróbuj funkcję:

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 ; 

Pozdrawiam.