繁体   English   中英

存储过程中按名称的Firebird SQL访问参数

[英]Firebird SQL access parameter by name in stored procedure

在Firebird(v1.5)存储过程中,是否可以通过名称访问输出参数? 结果字段应该是指定年份的月份,如果我不必复制12次代码,会更容易。

这是一个示例(最终代码比这更复杂):

SET TERM !!;

CREATE PROCEDURE MY_PROC (
  I_PARAM INTEGER)
RETURNS (
  O_PARAM_1 INTEGER, O_PARAM_2 INTEGER, O_PARAM_3 INTEGER, O_PARAM_4 INTEGER,
  O_PARAM_5 INTEGER, O_PARAM_6 INTEGER, O_PARAM_7 INTEGER, O_PARAM_8 INTEGER,
  O_PARAM_9 INTEGER, O_PARAM_10 INTEGER, O_PARAM_11 INTEGER, O_PARAM_12 INTEGER)
AS
  declare MONTH_ID INTEGER;
BEGIN
  MONTH_ID = 1;

  while (MONTH_ID <= 12) do
  begin
    select
      count(*)
    from
      MY_TABLE M
    where
      M.MONTH_ID = I
    into
>>>>  :O_PARAM_???; -- need access by name

    MONTH_ID = MONTH_ID + 1;
  end

  suspend;

END!!

SET TERM ;!!

这是不可能的。 Firebird需要在编译时知道它将使用哪个变量。 动态引用输出参数是不可能的。

作为中间解决方案,您可以将结果分配给一个临时变量,然后仅将其分配给if-else长链中的正确变量。 它仍然是代码重复,但比一遍又一遍的重复查询少。

您还可以执行一个查询,一次查询所有月份的结果。 这将导致轻微的代码膨胀,但可能会更有效:

select 
  (SELECT count(*) from MY_TABLE where MONTH_ID = 1),
  (SELECT count(*) from MY_TABLE where MONTH_ID = 2),
  (SELECT count(*) from MY_TABLE where MONTH_ID = 3),
  -- ...and so on
into :O_PARAM_1, :O_PARAM_2, :O_PARAM_3;

如果您使用更新的Firebird版本(例如Firebird 2.5),则可以使用CTE(尽管对于此简单查询而言,它并没有太多简化):

WITH counts AS (SELECT MONTH_ID, count(*) AS MONTH_COUNT from MY_TABLE M GROUP BY MONTH_ID)
select 
  (SELECT MONTH_COUNT from counts where MONTH_ID = 1),
  (SELECT MONTH_COUNT from counts where MONTH_ID = 2),
  (SELECT MONTH_COUNT from counts where MONTH_ID = 3),
  -- ...and so on
into :O_PARAM_1, :O_PARAM_2, :O_PARAM_3;

完全不同的解决方案是放弃可执行存储过程的想法(尽管在当前解决方案中存在SUSPEND的情况下,实际上实际上总是可以选择一行),而是使用将结果返回为行的可选择过程。 解决方案取决于您的实际数据需求。

CREATE PROCEDURE MY_PROC (
  I_PARAM INTEGER)
RETURNS (
  MONTH_ID INTEGER, MONTH_COUNT INTEGER)
AS
BEGIN
  FOR
    select MONTH_ID, count(*)
    from MY_TABLE M
    GROUP BY MONTH_ID
    into :MONTH_ID, :MONTH_COUNT
  BEGIN
    SUSPEND;
  END
END

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM