如何将拆分结果推送到数组PL SQL并使用引用游标返回数组数据

时间:2016-10-25 15:33:20

标签: arrays oracle plsql cursor

我正在尝试将分割结果推送到数组中,但我不知道该怎么做。这是我的存储过程:

   CODE_KZ_i NVARCHAR2 (4000):='';
   FTKZ NVARCHAR2 (4000):='';

   TYPE namesarray IS TABLE OF NVARCHAR2(4000);
   FTarray namesarray:=namesarray();
   i NUMBER;

开始

    FOR FTKZ IN ( SELECT REGEXP_SUBSTR (KZ,'[^;]+', 1,LEVEL)  TXT  FROM DUAL 
                  CONNECT BY REGEXP_SUBSTR (KZ,'[^;]+', 1, LEVEL) IS NOT NULL)

    LOOP

    FTarray.extend;

    IF CONTA = 0 THEN CODE_KZ:=FTKZ.TXT;
    ELSE 
    CODE_KZ:= FTKZ.TXT;

    END IF;

    FTarray(i):= CODE_KZ;
    DBMS_OUTPUT.put_line('FT:'|| FTarray(i));
    i:=i+1;
    CONTA:=CONTA+1;

我的目标是将FTKZ.TXT的结果推送到FTarray。有人能帮帮我吗?

下一步是在sys_refcursor中返回数组的数据。我在名为KZ的输入中得到一些代码,我必须返回另一个代码,链接到此表中的kz:SG_AN_FT

    open p_cur_result for
    SELECT DISTINCT FT.CODE as FT INTO P_RESULT FROM SG_AN_FT FT 
          INNER JOIN SG_BOM_PIVOT_PN_KZ BOM
          ON FT.ID = BOM.ID_FT
          INNER JOIN SG_AN_KZ K
          ON K.ID = BOM.ID_KZ
          WHERE K.CODE in (SELECT * FROM TABLE(cast(FTarray as FT));

    Errore(317,60): PL/SQL: ORA-00902: tipo di dati non valido

提前谢谢

1 个答案:

答案 0 :(得分:0)

你的循环代码看起来非常接近;为KZ添加定义和虚拟值并清理您可以执行的其他变量:

declare
  -- made up as not shown in the question
  KZ NVARCHAR2 (4000) := 'A;B;C;D';

  CODE_KZ NVARCHAR2 (4000);

  TYPE namesarray IS TABLE OF NVARCHAR2(4000);
  FTarray namesarray:=namesarray();
  CONTA NUMBER := 1;
begin
  FOR FTKZ IN ( SELECT REGEXP_SUBSTR (KZ,'[^;]+', 1,LEVEL)  TXT  FROM DUAL 
                CONNECT BY REGEXP_SUBSTR (KZ,'[^;]+', 1, LEVEL) IS NOT NULL)
  LOOP
    FTarray.extend;

    -- redundant as both branches do the same thing; also can't be zero
    IF CONTA = 0 THEN
      CODE_KZ:=FTKZ.TXT;
    ELSE 
      CODE_KZ:= FTKZ.TXT;
    END IF;

    FTarray(CONTA):= CODE_KZ;
    DBMS_OUTPUT.put_line('FT:'|| FTarray(CONTA));
    CONTA:=CONTA+1;
  END LOOP;
end;
/

PL/SQL procedure successfully completed.

FT:A
FT:B
FT:C
FT:D

您的IF CONTA = 0检查表明您正在使用索引零启动循环,这将获得ORA-06532: Subscript outside of limit,因为集合从一个非零开始索引。无论如何,当您为两个分支中的变量分配相同的值时,该检查似乎是多余的,因此您可以直接将FTKZ.TXT分配给新扩展的数组元素。您根本不需要CONTACODE_KZ

declare
  -- made up as not shown in the question
  KZ NVARCHAR2 (4000) := 'A;B;C;D';

  TYPE namesarray IS TABLE OF NVARCHAR2(4000);
  FTarray namesarray:=namesarray();
begin
  FOR FTKZ IN ( SELECT REGEXP_SUBSTR (KZ,'[^;]+', 1,LEVEL)  TXT  FROM DUAL 
                CONNECT BY REGEXP_SUBSTR (KZ,'[^;]+', 1, LEVEL) IS NOT NULL)
  LOOP
    FTarray.extend;
    FTarray(FTArray.count) := FTKZ.TXT;
    DBMS_OUTPUT.put_line('FT:'|| FTarray(FTArray.count));
  END LOOP;
end;
/

PL/SQL procedure successfully completed.

FT:A
FT:B
FT:C
FT:D

但您也不需要使用循环you can use bulk collect to populate your collection in one go

declare
  -- made up as not shown in the question
  KZ NVARCHAR2 (4000) := 'A;B;C;D';

  TYPE namesarray IS TABLE OF NVARCHAR2(4000);
  FTarray namesarray:=namesarray();
begin
  SELECT REGEXP_SUBSTR (KZ,'[^;]+', 1,LEVEL) TXT
  BULK COLLECT INTO FTarray
  FROM DUAL 
  CONNECT BY REGEXP_SUBSTR (KZ,'[^;]+', 1, LEVEL) IS NOT NULL;

  FOR i IN 1..FTarray.count LOOP
    DBMS_OUTPUT.put_line('FT:' || FTarray(i));
  END LOOP;
end;
/

PL/SQL procedure successfully completed.

FT:A
FT:B
FT:C
FT:D