2013-10-10 42 views
5

我有火鳥(它在我奔跑使用FlameRobin)大型查詢,使用參數所有的地方,但得到下面的查詢運行就可以了:定義變量和使用EXECUTE運行一個查詢塊

SELECT * FROM customers WHERE customerid = 1234; 

我想將1234定義爲一個變量,比如customerID,這樣我就可以很容易地用其他東西替換它。

我明白了,我需要把它放在EXECUTE BLOCK之內。

EXECUTE BLOCK 
AS 
DECLARE customerID INT = 1234; 

BEGIN 
    SELECT * FROM customers WHERE customerid = :customerID 
END 

如果任何重要的,我得到的錯誤是Engine Message : Dynamic SQL Error SQL error code = -104 Unexpected end of command - line 3, column 26

回答

10

的問題是,FlameRobin需要知道語句結束和下一個語句開始的時候。默認情況下,它使用分號(;)。然而EXECUTE BLOCK本質上是一個存儲過程,它不存儲在數據庫中,所以它包含PSQL代碼,它也使用分號作爲語句分隔符。

這樣做的後果是,你會得到語法錯誤,因爲FlameRobin正在向服務器發送不完整的語句(即:它在每個遇到的;後發送語句)。

您需要指示FlameRobin使用使用SET TERM的不同語句終止符。其他Firebird查詢工具(如isql)也需要這樣的工具,但它實際上並不是Firebird本身的語法的一部分!

所以,你需要執行代碼爲:

-- Instruct flamerobin to use # as the terminator 
SET TERM #; 
EXECUTE BLOCK 
AS 
DECLARE customerID INT = 1234; 

BEGIN 
    SELECT * FROM customers WHERE customerid = :customerID; 
END# 
-- Restore terminator to ; 
SET TERM ;# 

但是這樣做仍然會產生一個錯誤,因爲這種查詢是PSQL無效:在PSQL塊A SELECT需要INTO子句映射列到變量。而獲得的值了EXECUTE BLOCK返還給FlameRobin您還需要指定一個RETURNS條款作爲documentation of EXECUTE BLOCK描述:據

-- Instruct flamerobin to use # as the terminator 
SET TERM #; 
EXECUTE BLOCK 
    RETURNS (col1 INTEGER, col2 VARCHAR(100)) 
AS 
DECLARE customerID INT = 1234; 

BEGIN 
    SELECT col1, col2 FROM customers WHERE customerid = :customerID INTO :col1, :col2; 
    SUSPEND; 
END# 
-- Restore terminator to ; 
SET TERM ;# 

我所知SUSPEND技術上這裏不需要,但Flamerobin不會如果沒有包含返回的行,則獲取它。

但是,如果選擇產生多行,上述不會工作。對於那些需要使用FOR SELECT ... DOSUSPEND組合:

-- Instruct flamerobin to use # as the terminator 
SET TERM #; 
EXECUTE BLOCK 
    RETURNS (col1 INTEGER, col2 VARCHAR(100)) 
AS 
DECLARE customerID INT = 1234; 

BEGIN 
    FOR SELECT col1, col2 FROM customers WHERE customerid = :customerID INTO :col1, :col2 
    DO 
    SUSPEND; 
END# 
-- Restore terminator to ; 
SET TERM ;# 

SUSPEND這裏返回該行並等待來電者已經獲取該行,然後用FOR繼續循環。這樣它會迭代結果。

恕我直言,這太多的努力參數化。你可能想在使用flamerobin時考慮簡單的不參數化,或者使用支持爲Firebird的普通參數佔位符詢問參數值的工具(但老實說我不確定是否有)。

+0

您的示例工作完美。感謝您的答覆。實施它確實付出了太多的努力,我將不得不改變很多查詢。但至少我知道我在錯誤的門口知道。 –

-2
SET TERM #; 
EXECUTE BLOCK 
RETURNS (COL1 Varchar(5) , COL2 INTEGER , COL3 INTEGER) 
AS 
DECLARE customerID INT = 5; 
BEGIN 
    FOR SELECT COSP.OSP_COMPON,COSP.OSP_DIAS FROM COSP WHERE COSP.OSP_ORDEM=2 INTO COL1 , COL3 
    DO 
    FOR SELECT CMES.MESNUM FROM CMES WHERE CMES.MESNUM = customerID INTO COL2 DO SUSPEND; 
    SUSPEND; 
END# 
SET TERM ;# 

爲什麼會下降?