2012-01-28 30 views
5

我有一個函數,我目前在PHP中使用編譯從不同的字段郵寄地址,但考慮到不同的格式在不同的地區使用。我試圖複製這個MySQL存儲函數。我意識到,在代碼中而不是在數據庫中執行這種事情通常會更快,但是我們的Intranet有一種方式讓人們以只讀方式輸入原始MySQL SELECT命令,以便他們可以構建高級搜索並保存查詢。這個特定的功能將被使用,以便用戶可以將他們的高級搜索查詢結果輸出到標籤佈局。MySQL存儲函數與嵌套的IF ... END如果語法錯誤,使用正確的語法附近''

當我嘗試和存儲使用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和得到同樣的錯誤,而且它的一個突出「END附近的SQL語法錯誤」,所以它不僅僅是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中看到導致此問題的原因嗎?
一旦我已經存儲了函數,那麼我可以測試它並調整邏輯。

此外,如果有任何東西可以簡化功能,然後讓我知道。這裏沒有太多的例子,所以我已經有點補丁了。

回答

7

好我要回答我的問題。感謝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,但我對邏輯做了一些調整。

所以我所有的錯和RTM

2

你缺少一個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;; 
+0

不好運我恐怕:( – batfastad 2012-01-28 22:05:48

+0

@batfastad那'END IF;'可能不是唯一缺少的東西......但我沒有安裝MySQL來檢查它... – Yahia 2012-01-28 22:06:56

+0

夠公平的,我我會很快檢查我的嵌套是否匹配。乾杯:) – batfastad 2012-01-28 22:08:26

5

其他解決方案。試用一個功能:

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 ; 

問候。