的問題是,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 ... DO
與SUSPEND
組合:
-- 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的普通參數佔位符詢問參數值的工具(但老實說我不確定是否有)。
您的示例工作完美。感謝您的答覆。實施它確實付出了太多的努力,我將不得不改變很多查詢。但至少我知道我在錯誤的門口知道。 –