理解Oracle中的MultiSet及其优势和重要性

k4ymrczo  于 2023-08-04  发布在  Oracle
关注(0)|答案(2)|浏览(203)

我已经看到了很多答案的使用Multiset & AS SYS.ODCIVARCHAR2LIST等。我不能理解背后的逻辑/它是如何工作的。请看下面的例子(实际上取自另一个问题)。请您解释工作流程/工作,以了解多集。是的,我试图阅读与此相关的文件。

CREATE TABLE table_name ( Id, Column1, Column2 ) AS
SELECT 1, 'A,B,C', 'H' FROM DUAL UNION ALL
SELECT 2, 'D,E',   'J,K' FROM DUAL UNION ALL
SELECT 3, 'F',     'L,M,N' FROM DUAL;

字符串

查询

SELECT t.id,
       c1.COLUMN_VALUE AS c1,
       c2.COLUMN_VALUE AS c2
FROM   table_name t
       CROSS JOIN
       TABLE(
         CAST(
           MULTISET(
             SELECT REGEXP_SUBSTR( t.Column1, '[^,]+', 1, LEVEL )
             FROM   DUAL
             CONNECT BY LEVEL <= REGEXP_COUNT( t.Column1, '[^,]+' )
           ) AS SYS.ODCIVARCHAR2LIST
         )
       ) c1
       CROSS JOIN
       TABLE(
         CAST(
           MULTISET(
             SELECT REGEXP_SUBSTR( t.Column2, '[^,]+', 1, LEVEL )
             FROM   DUAL
             CONNECT BY LEVEL <= REGEXP_COUNT( t.Column2, '[^,]+' )
           ) AS SYS.ODCIVARCHAR2LIST
         )
       ) c2

结果:

| ID | C1 | C2 |
|----|----|----|
|  1 |  A |  H |
|  1 |  B |  H |
|  1 |  C |  H |
|  2 |  D |  J |
|  2 |  D |  K |
|  2 |  E |  J |
|  2 |  E |  K |
|  3 |  F |  L |
|  3 |  F |  M |
|  3 |  F |  N |


先谢谢你。

7fhtutme

7fhtutme1#

Oracle提供了三种不同类型的集合,在其他语言中,术语“数组”更常见。

  • 关联数组(或索引方式表)
  • VARRAY(可变大小数组)
  • 嵌套表

请查看集合类型,以了解它们的差异以及可以使用哪种类型。
从简单的事情开始,例如

create type number_table_type as table of number;

字符串
您可以以多种方式使用它们,三个selects是等效的。它们都选择表emp并将emp_id值存储到嵌套表emp_T中。

create table emp (
    emp_id number,
    emp_name varchar2(100));

insert into emp values (10, 'Scott');
insert into emp values (20, 'King');
insert into emp values (30, 'Tiger');

declare
   emp_T number_table_type:
begin
   select cast(collect(emp_id) as number_table_type)
   into emp_T
   from emp;

   select emp_id
   bulk collect into emp_T
   from emp;

   SELECT CAST(MULTISET(SELECT emd_id FROM emp) AS number_table_type)
   into emp_T
   FROM dual;

   emp_T := number_table_type(10,20,30);
   
   for i in 1..3 loop
       emp_T.EXTEND;
       emp_T(i) := 10*i;
   end loop;
end;


相反,即。使用TABLE函数将嵌套表转换为“正常”表:

select *
from TABLE(emp_T);


Oracle提供了多集运算符和多集条件。它们提供了连接两个数组,使值不同等功能。很多时候我看到开发人员在他们的代码中编写LOOP,其中多集运算符/条件将用单个命令完成相同的事情。
一旦你熟悉了这些基本的数组,你也可以尝试更复杂的结构。然而,根据我的感觉,这种复杂的结构在培训材料和文档中很常见,但在“真实的生活”中却很少使用。Oracle的优势在于存储和操作关系数据,而不是面向对象的数据。
SYS.ODCIVARCHAR2LIST,et al.只是一些预定义的类型。实际上,使用它们还是创建自己的类型并不重要。

dpiehjr4

dpiehjr42#

那么,您应该从最深的层次查看这样的代码并向上导航,以便弄清楚发生了什么。
这是基于表的第一行:正如你所看到的,“regexp”magic 将你的逗号分隔值(即列)分成行。

SQL> with test as
  2    (select 1, 'A,B,C' column1 from dual)
  3  select regexp_substr(t.column1, '[^,]+', 1, level)
  4  from test t
  5  connect by level <= regexp_count(t.column1, '[^,]+');

REGEXP_SUBSTR(T.COLU
--------------------
A
B
C

SQL>

字符串
MULTISET创建这些值的“集合”,而CAST将其“转换”为SYS.ODCIVARCHAR2LIST类型。正如您所看到的,它由SYS拥有,并且就像您创建了自己的类型(使用CREATE TYPE命令)一样,其中包含VARCHAR2值。当类型像这样“简单”时,或者包含数字的类型(因此您可以使用SYS.ODCINUMBERLIST),您可以使用预定义的类型而不是创建自己的类型。因此,该集合包含A、B和C。
最后,TABLE函数生成一个可以查询的行的集合,就好像它是一个“普通”表一样。

相关问题