如何向Firebird存储过程输入值的数组参数?

dat*_*aol 10 sql arrays parameters firebird

我想向Firebird存储过程输入ID 的数组参数.

:INPUT_LIST_ID = [1,2,12,45,75,45]

我需要执行这个SQL命令:

SELECT *
FROM CITY
WHERE ID_CITY IN (:INPUT_LIST_ID)
Run Code Online (Sandbox Code Playgroud)

可能吗?谢谢!

小智 10

你也可以使用这样的东西:

SELECT *
FROM CITY
WHERE ID_CITY IN (SELECT ID FROM GetIntegerList('1, 2, 12, 45, 75, 45'))
Run Code Online (Sandbox Code Playgroud)

您必须创建一个名为"GetIntegerList"的新Firebird过程,它看起来像这样:

CREATE OR ALTER PROCEDURE "GETINTEGERLIST"("AINTEGERLIST" VARCHAR(32000))
returns (
  ID integer
)
as
  declare variable IntegerList varchar(32000);
  declare variable CommaPos integer;
  declare variable IntegerVal varchar(10);
begin
  IntegerList = AIntegerList || ' ';
  CommaPos = Position(',', IntegerList);

  while (CommaPos > 0) do
  begin
    IntegerVal = Trim(SubString(IntegerList from 1 for CommaPos - 1));

    if (Char_Length(IntegerVal) > 0) then
    begin
      if (IntegerVal similar to '[0-9]*') then
      begin
        ID = Cast(IntegerVal as integer);
        suspend;
      end
    end

    if (Char_Length(IntegerList) > CommaPos) then
      IntegerList = SubString(IntegerList from CommaPos + 1);
    else
      IntegerList = '';

    CommaPos = Position(',', IntegerList);
  end

  IntegerList = Trim(IntegerList);

  if (Char_Length(IntegerList) > 0) then
  begin
    if (IntegerList similar to '[0-9]*') then
    begin
      ID = Cast(IntegerList as integer);
      suspend;
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

注意,这是在Firebird 2.5.2中完成的.


ain*_*ain 5

AFAIK不,那不可能。尽管Firebird确实具有数组数据类型,但它是基本的支持,并且通常不建议使用数组。我认为最简单的解决方案是将数组作为(逗号分隔)字符串传递,然后使用该for execute statement语句获取结果集,例如

create procedure CITY (INPUT_LIST_ID varchar(1024)) 
returns( ... )
as
begin
  for execute statement
    'select ... from T where ID_CITY IN ('|| INPUT_LIST_ID ||')' into ...
  do begin
     suspend;
  end
end
Run Code Online (Sandbox Code Playgroud)

但是,这意味着您用来获取结果的语句也会更改,而不是WHERE使用存储过程的参数CITY

SELECT * FROM CITY('1, 2, 12, 45, 75, 45')
Run Code Online (Sandbox Code Playgroud)

发送参数列表的另一种方法是使用全局临时表。它的优点是您可以发送大量的ID,而不会超过允许的最大语句大小,但是设置调用的工作更多。

create global temporary table SP_CITY_PARAMS (
  id int not null primary key
)
on commit delete rows;

create procedure CITY
returns( ... )
as
begin
  for select ... from T where ID_CITY IN (
      select id from SP_CITY_PARAMS
  ) into ...
  do begin
     suspend;
  end
end
Run Code Online (Sandbox Code Playgroud)

  • @dataol考虑使用[全局临时表](http://www.firebirdsql.org/file/documentation/reference_manuals/reference_material/html/langrefupd25-ddl-table.html),插入所选城市,并加入该城市。 (2认同)