【问题标题】:Combine 2 VARRAYS Oracle PL/SQL结合 2 个 VARRAYS Oracle PL/SQL
【发布时间】:2020-10-20 16:25:53
【问题描述】:

我有一个返回代码数组 (NUMBER) 的函数。

select GET_USER_OFFICE_CODES(10) FROM DUAL;
--output--
DB.OFFICE_CODES(3,4,5,6,7,8,9)

select GET_USER_OFFICE_CODES(2) FROM DUAL;    
--output--
DB.OFFICE_CODES(1,10,14,21)

在一个函数中,我试图组合 2 个相同类型的数组。我收到一个错误“调用'MULTISET_UNION_ALL'的参数类型错误”

create or replace function COMBINE_OFFICE_CODES(
  in_local_office_code NUMBER,
  in_regional_office_code NUMBER
)
RETURN OFFICE_CODES
IS
  local_office_codes OFFICE_CODES;
  regional_office_codes OFFICE_CODES;
  combined_office_codes OFFICE_CODES; 
Begin
  local_office_codes := GET_USER_OFFICE_CODES(in_local_office_code);
  regional_office_codes := GET_USER_OFFICE_CODES(in_regional_office_code);
  combined_office_codes := local_office_codes MULTISET UNION ALL regional_office_codes;

  RETURN combined_office_codes;
end

【问题讨论】:

  • "Multiset" 操作符适用于多集(显然),在 Oracle 中称为“嵌套表”。它们不适用于数组(Oracle 中的 varray)。数组是一个 ORDERED 值序列;没有“数组的联合”的概念。您真的需要那里的数组,还是可以更改为嵌套表?这将是最有意义的。如果您确实需要数组,也可以对其进行排列 - 它有点复杂,您需要在 UNION 中指定您想要的顺序。 (同样,如果你的答案是“顺序无关紧要”,那么你不需要数组,你需要嵌套表)。
  • 感谢您的帮助。将 TYPE 更改为 TABLE 就可以了。创建或替换类型 OFFICE_CODES 作为数字表;

标签: oracle plsql oracle-apex-5.1


【解决方案1】:

你可以使用 UNION ALL;

create type OFFICES_CODES is varray(100) of number;

declare
  local_office_codes OFFICES_CODES := OFFICES_CODES(1,2);
  regional_office_codes OFFICES_CODES := OFFICES_CODES(3,4);
  combined_office_codes OFFICES_CODES; 
Begin

  SELECT * BULK COLLECT INTO  combined_office_codes FROM  
  (select *from table(local_office_codes) 
    UNION ALL  
  select *from table(regional_office_codes));
 
 FOR i in 1..combined_office_codes.count loop
    DBMS_OUTPUT.PUT_LINE(combined_office_codes(i));
 end loop;
 
end;
/

声明已处理。 1 2 3 4

******************EIDT *********

您还可以摆脱局部变量并直接使用函数。 试试这个:

create or replace type OFFICES_CODES is varray(100) of number;

create or replace function  get_office_codes (nNum number) return OFFICES_CODES
is
vRet offices_codes;
begin
    if nNum = 1 then
        vRet := offices_codes(1,4);
    else
        vRet := offices_codes(3,6);
    end if;
    return vRet;
end;
/


declare
  combined_office_codes OFFICES_CODES; 
Begin

  SELECT * BULK COLLECT INTO  combined_office_codes FROM  
  (select * from table(get_office_codes(1)) 
    UNION ALL  
  select *from table(get_office_codes(2))
  ORDER BY 1);
 
 FOR i in 1..combined_office_codes.count loop
    DBMS_OUTPUT.PUT_LINE(combined_office_codes(i));
 end loop;
 
end;
/

【讨论】:

  • 这种方法没有多大意义。 “数组”表示顺序很重要。解决方案中的数组将具有随机的元素顺序。即使您尝试解决此问题,也不清楚它是否可能;不知道 TABLE 运算符是否会按数组顺序生成元素。在一些看似正确的简单示例中,但绝对没有记录。另一方面,正如我已经告诉 OP 的那样,如果顺序不重要,那么他不应该首先使用数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-12
  • 2011-06-10
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多