【问题标题】:Is it possible to return multiple rows in a Firebird's stored procedure?是否可以在 Firebird 的存储过程中返回多行?
【发布时间】:2017-02-14 19:45:47
【问题描述】:

我想知道是否可以在 Firebird 1.5 的 SELECT 查询中返回不止一行,如下所示:

| FIELD1 | FIELD 2 |
--------------------
| 1.00   | 1       |
| 2.00   | 2       |
| 3.00   | 3       |

SET TERM /;

CREATE OR ALTER PROCEDURE TEST
RETURNS (VARIABLE1 DOUBLE PRECISION, VARIABLE2 INTEGER)
AS
BEGIN
  SELECT FIELD1, FIELD2 FROM TABLE INTO :VARIABLE1, :VARIABLE2;
END/

EXECUTE PROCEDURE TEST/

SET TERM ;/

假设查询返回多个结果/行,则抛出以下错误:

语句失败,SQLCODE = -811

单例选择中的多行

显然,Firebird 的引擎不允许我在一个变量中返回多个值。我正在开发一个 Python 的软件,我想在其中获得一个元组,例如,基于过程 TEST。我正在使用 kinterbasdb 模块与 GDB 连接。

有没有办法做到这一点?

【问题讨论】:

标签: sql stored-procedures firebird


【解决方案1】:

火鸟有两个types of stored procedures

  • 可执行过程最多产生一行,并使用以下命令执行:

      execute procedure <procedurename>
    
  • 可选择的过程可以产生多行并使用以下命令执行:

      select * from <procedurename>
    

    或者带参数:

      select * from <procedurename>(param, ...)
    

可选择的过程包含SUSPEND 关键字,它输出行并等待下一次提取。这个关键字的存在是区分这两种类型的唯一因素。

警告:可以将execute procedure 与可选过程一起使用,但在这种情况下,它只会产生一行,并且在第一行产生后执行将结束:@ 之后的存储过程的其余部分987654329@不会被执行!过去也可以从可执行的存储过程中“选择”,但在 Firebird 3 中不再可能。

报错的具体原因“Multiple rows in singleton select”是一行:

SELECT FIELD1, FIELD2 FROM TABLE INTO :VARIABLE1, :VARIABLE2;

这个select ... into ... 语句只允许产生单行(又名单例选择)。如果您预计不止一行,则需要使用 for select ... into ... do,它允许您遍历结果行。

将其与suspend 结合将导致:

CREATE OR ALTER PROCEDURE TEST
RETURNS (VARIABLE1 DOUBLE PRECISION, VARIABLE2 INTEGER)
AS
BEGIN
  FOR SELECT FIELD1, FIELD2 FROM TABLE INTO :VARIABLE1, :VARIABLE2
  DO
  BEGIN
      SUSPEND;
  END
END

BEGIN ... END-block 在技术上不是必需的,但我更喜欢在这里总是使用一个块。

然后您可以使用以下命令执行此操作:

select variable1, variable2 from test;

【讨论】:

    【解决方案2】:

    您需要的是“可选存储过程”。基本上,您必须将代码更改为以下内容:

    CREATE OR ALTER PROCEDURE TEST
    RETURNS (VARIABLE1 DOUBLE PRECISION, VARIABLE2 INTEGER)
    AS
    BEGIN
      for SELECT FIELD1, FIELD2 FROM TABLE INTO :VARIABLE1, :VARIABLE2
       do SUSPEND;
    END
    

    并使用 SELECT 调用该过程,如下所示:

    SELECT * FROM TEST;
    

    祝你好运!

    【讨论】:

    猜你喜欢
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多