【问题标题】:How to SELECT a PROCEDURE in Firebird 2.5如何在 Firebird 2.5 中选择程序
【发布时间】:2011-07-07 21:04:01
【问题描述】:

我正在使用 Firebird Embedded v2.5。如何在查询(SELECT)中使用过程?

我的程序:

SET TERM ^ ;
CREATE PROCEDURE FN_TEST( Y INTEGER )
RETURNS( X INTEGER)
AS
BEGIN
X = Y + 1;
END^
SET TERM ; ^

我想列出一些程序修改过的表的一些字段,像这样:

SELECT some_table_field_1, 
       fn_test( 4 ) AS zzz, 
       some_table_field_2,
       fn_test( some_table_field_2 ) AS field_2_modified
FROM   tb_test

需要结果(表格):

some_table_field_1     zzz         some_table_field_2      field_2_modified
---------------------------------------------------------------------------
aaa                    5           14                      15
bbb                    5           23                      24
www                    5           75                      76

这东西在 PostgreSQL 中运行良好,但我不知道如何在 Firebird 中做到这一点。

【问题讨论】:

  • 您的问题到底是什么?您收到错误消息吗?如果是,请发布它

标签: select stored-procedures firebird firebird2.5


【解决方案1】:
SELECT some_table_field_1, 
   (select X from fn_test( 4 )) AS zzz, 
   some_table_field_2,
   (select X from fn_test( some_table_field_2 )) AS field_2_modified
FROM   tb_test

【讨论】:

  • fn_test 不可选择(它是executable procedure)。建议的解决方案会产生 invalid request BLR at offset... 错误。
  • 添加暂停;语句就在 END^ 语句之前,函数变为可选择的。
【解决方案2】:

FN_TEST 是一个可执行过程:它可以通过EXECUTE PROCEDURE 语句调用并返回一组输出参数。

在 Firebird 2.x 中,只有一个可选存储过程可以“用作”视图/表格(参见Firebird Stored Procedures)。

所以:

SELECT FN_TEST(some_table_field) AS field_modified
FROM   tb_test

在偏移处产生一个无效的请求 BLR... 错误。

您可以将您的程序更改为suggested,但实际上,您需要的功能已在Firebird 3 中以stored function 的形式引入:

CREATE FUNCTION FN_TEST(Y INT) RETURNS INT
AS
BEGIN
  RETURN Y + 1;
END;

SELECT FN_TEST(4) AS zzz
FROM   tb_test

Functions with PSQL in Firebird 3 中的更多详细信息。

【讨论】:

    【解决方案3】:

    试试

    SELECT some_table_field_1, 
       fn_test.x AS zzz, 
       some_table_field_2,
    FROM   tb_test
    LEFT JOIN fn_test(some_table_field_1) ON (1 = 1)
    

    【讨论】:

    • fn_test 不可选择(它是executable procedure)。建议的解决方案会产生 invalid request BLR at offset... 错误。
    【解决方案4】:

    使用 UDF 来管理字段的计算。 存储过程只能在 FROM 子句中使用。

    【讨论】:

      【解决方案5】:

      试试这个

      SET TERM ^ ;
      CREATE PROCEDURE FN_TEST( Y INTEGER )
      RETURNS( X INTEGER)
      AS
      BEGIN
      X = Y + 1;
      SUSPEND;
      END^
      SET TERM ; ^
      

      【讨论】:

        【解决方案6】:

        作为JustMe said,您不能在选择中调用存储过程。您只能在 FROM 部分调用存储过程。您的问题的另一个解决方案是创建一个像这样的可选过程:

        create or alter procedure myproc (
         n integer)
        returns (
         field_1 integer,
         zzz integer,
         field_2 integer,
         modified_field_2 integer)
        as
        declare variable i integer;
        begin
          for
            select some_table_field_1, :n+1 as zzz, some_table_field_2, (some_table_field_2+1) as field_2_modified
            from tb_test
            into :field_1, :zzz, :field_2, :modified_field_2
          do begin
            suspend;
          end
        end
        

        运行该代码后,您可以简单地查询select * from myproc(4) 并得到您想要的。

        【讨论】:

          【解决方案7】:

          您不能在 Firebird 的选择列表中调用存储过程。您必须编写具有期望结果的可选过程或编写 UDF 函数来执行 fn_test 过程中的操作。

          对于您的情况,最简单的方法是:

          SELECT some_table_field_1, 
                 5 AS zzz, 
                 some_table_field_2,
                 ( some_table_field_2 + 1) AS field_2_modified
          FROM   tb_test
          

          【讨论】:

            【解决方案8】:

            可以使用 EXECUTE BLOCK 请看EXECUTE BLOCK

            【讨论】:

              猜你喜欢
              • 2014-02-02
              • 2017-06-22
              • 2018-11-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-12-05
              相关资源
              最近更新 更多