我在Firebird中有一个大型查询(我使用FlameRobin运行),在整个地方都使用了一个参数,但是让下面的查询运行会:
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
答案 0 :(得分:14)
问题是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块中的SELECT
需要INTO
子句将列映射到变量。要从EXECUTE BLOCK
返回FlameRobin中获取值,您还需要指定documentation of EXECUTE BLOCK
中所述的RETURNS
子句:
-- 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将不会获取返回的行。
但是,如果select产生多行,则上述操作无效。为此,您需要将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的常规参数占位符请求参数值的工具(但说实话我不确定是否有)。
答案 1 :(得分:-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 ;#
为什么会跌倒?