转换为表格后如何获取VARRAY项目的索引

时间:2012-05-11 23:09:44

标签: sql oracle collections

在以下示例中,我创建了一个包含3个项目的VARRAY。

TEST@XE> select t1, t2.* from
  2  (select 'X' as t1 from dual UNION select 'Y' from dual) t1,
  3  table (sys.odcivarchar2list('a', 'b', 'c'))             t2;

T1  COLUMN_VALUE
--- --------------------
X   a
X   b
X   c
Y   a
Y   b
Y   c

我想得到以下输出:

T1  INDEX COLUMN_VALUE
--- ----- --------------------
X   1     a
X   2     b
X   3     c
Y   1     a
Y   2     b
Y   3     c

请注意,sys.odcivarchar2list预定义为VARRAY(32767) OF VARCHAR2(4000);

3 个答案:

答案 0 :(得分:2)

据我所知,没有任何纯SQL解决方案可以保证正常工作。您可能需要创建一个PL / SQL函数来将VARRAR2的VARRAY转换为VARRAY对象。

即使对于下面的PL / SQL解决方案,也很难说它能够保证正常工作。我在PL/SQL Language Reference中找不到任何明确表示构造函数中的项的顺序将始终与索引顺序匹配的内容。但是这些例子意味着命令被保留了,如果它不是真的,它会导致我现在可能会遇到的各种奇怪的错误..

请注意,我的示例可能适用于嵌套表。从手册:

  

“当您从数据库中存储和检索varray时,它的索引   和元素顺序保持稳定。“...”a的索引和行顺序   存储和检索时,嵌套表可能不会保持稳定   来自数据库的嵌套表。“


SQL> create or replace type varchar2_with_index as object
  2  (
  3     id number,
  4     value varchar2(4000)
  5  );
  6  /

Type created.

SQL> create or replace type varchar2_with_index_varray as
  2     varray(32767) of varchar2_with_index;
  3  /

Type created.

SQL> create or replace function add_index(p_list in sys.ODCIVarchar2List
  2  ) return varchar2_with_index_varray as
  3     v_new_list varchar2_with_index_varray := varchar2_with_index_varray();
  4  begin
  5     for i in 1 .. p_list.count loop
  6             v_new_list.extend;
  7             v_new_list(v_new_list.count) := varchar2_with_index(i, p_list(i));
  8     end loop;
  9     return v_new_list;
 10  end;
 11  /

Function created.

SQL> column value format a6
SQL> select t1, t2.* from
  2  (select 'X' as t1 from dual UNION select 'Y' from dual) t1,
  3  table (add_index(sys.odcivarchar2list('a', 'b', 'c')))  t2;

T         ID VALUE
- ---------- ------
X          1 a
X          2 b
X          3 c
Y          1 a
Y          2 b
Y          3 c

6 rows selected.

答案 1 :(得分:1)

 select t1, row_number() over ( partition by t1 order by t1), t2.* from
 (select 'X' as t1 from dual UNION select 'Y' from dual) t1,
 table (sys.odcivarchar2list('a', 'b', 'c'))             t2;

答案 2 :(得分:0)

我想知道为什么没有人想出这个,所以我正在回答我自己的问题

select t1, t2.* from 
(select 'X' as t1 from dual UNION select 'Y' from dual) t1, 
(select ROWNUM rn, COLUMN_VALUE from table (sys.odcivarchar2list('a', 'b', 'c'))) t2

T1          RN COLUMN_VALUE
--- ---------- --------------------
X            1 a
X            2 b
X            3 c
Y            1 a
Y            2 b
Y            3 c

然而,问题仍然是,这实际上是否保证100%工作