问题是 FlameRobin 需要知道一个语句何时结束以及下一个语句何时开始。默认情况下,它;
为此使用分号 ( )。然而 anEXECUTE 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 无效:SELECT
PSQL 块中的 A 需要一个INTO
子句将列映射到变量。并且EXECUTE BLOCK
要从返回给 FlameRobin 的值中获取值,您还需要指定一个RETURNS
子句,如以下文档中所述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
与 a 结合使用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 的普通参数占位符询问参数值的工具(但老实说,我不确定是否有任何参数值)。