4

In the following example I create a VARRAY with 3 items.

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

I'd like to have the following output:

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

Note that sys.odcivarchar2list is predefined as VARRAY(32767) OF VARCHAR2(4000);.

4

3 回答 3

2

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

即使对于下面的 PL/SQL 解决方案,也很难说它可以保证工作。我在PL/SQL 语言参考中找不到任何明确说明构造函数中项目的顺序将始终与索引顺序匹配的内容。但是这些例子暗示顺序是保留的,如果它不是真的,它会导致我现在可能会遇到的各种奇怪的错误..

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

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


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.
于 2012-05-12T21:21:06.037 回答
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;
于 2012-05-12T09:48:01.840 回答
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% 有效

于 2012-05-14T08:37:29.300 回答