如何从oracle表对象中检索唯一列值

问题描述 投票:0回答:1

我有一个oracle表类型对象,只想从特定列中检索唯一值,而无需使用索引进行循环。

例如,我想用这样的东西来实现。

 SELECT SET (NUMBER_TBL.S_NO)
   INTO NumbersTab
   FROM dual;
oracle plsql
1个回答
3
投票

您需要从对象类型中提取列,然后重新聚合为简单类型的集合,然后可以使用SET()函数:

Oracle设置

CREATE TYPE NUMBER_OBJ AS OBJECT( s_no NUMBER )
/
CREATE TYPE NUMBER_TBL AS TABLE OF NUMBER_OBJ
/
CREATE TYPE number_list AS TABLE OF NUMBER
/

CREATE TABLE test_data ( numbers NUMBER_TBL )
NESTED TABLE numbers STORE AS test_data__numbers
/
BEGIN
  INSERT INTO test_data
  VALUES (
    NUMBER_TBL(
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 2 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 4 )
    )
  );

  INSERT INTO test_data
  VALUES (
    NUMBER_TBL(
      NUMBER_OBJ( 5 ),
      NUMBER_OBJ( 5 ),
      NUMBER_OBJ( 5 ),
      NUMBER_OBJ( 6 ),
      NUMBER_OBJ( 6 ),
      NUMBER_OBJ( 5 )
    )
  );
END;
/

SQL查询

SELECT SET( CAST( COLLECT( n.s_no ORDER BY n.s_no ) AS number_list ) )
FROM   test_data t
       CROSS JOIN TABLE( t.numbers ) n
GROUP BY t.rowid

输出

| SET(CAST(COLLECT(N.S_NOORDERBYN.S_NO)ASNUMBER_LIST)) |
|------------------------------------------------------|
|                                              1,2,3,4 |
|                                                  5,6 |

SQLFiddle

PL / SQL选项1-SET

DECLARE
  n_tbl NUMBER_TBL := NUMBER_TBL(
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 2 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 4 )
    );
  NumbersTab number_list;
BEGIN
  SELECT SET(
           CAST(
             COLLECT( s_no ORDER BY s_no )
             AS number_list
           )
         )
  INTO   NumbersTab
  FROM   TABLE( n_tbl );

  FOR i IN 1 .. NumbersTab.COUNT LOOP
    DBMS_OUTPUT.PUT( NumbersTab(i) || ',' );
  END LOOP;
  DBMS_OUTPUT.PUT_LINE( '' );
END;
/

PL / SQL选项2-使用SET]不使用SQL ::

DECLARE
  n_tbl NUMBER_TBL := NUMBER_TBL(
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 2 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 4 )
    );
  NumbersTab number_list;
BEGIN
  NumbersTab := number_list();
  NumbersTab.EXTEND( n_tbl.COUNT );
  FOR i IN 1 .. n_tbl.COUNT LOOP
    NumbersTab(i) := n_tbl(i).s_no;
  END LOOP;
  NumbersTab := SET( NumbersTab );

  FOR i IN 1 .. NumbersTab.COUNT LOOP
    DBMS_OUTPUT.PUT( NumbersTab(i) || ',' );
  END LOOP;
  DBMS_OUTPUT.PUT_LINE( '' );
END;
/

PL / SQL选项3-BULK COLLECT INTO

DECLARE
  n_tbl NUMBER_TBL := NUMBER_TBL(
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 2 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 4 )
    );
  NumbersTab number_list;
BEGIN
  SELECT DISTINCT s_no
  BULK COLLECT INTO NumbersTab
  FROM   TABLE( n_tbl )
  ORDER BY s_no;

  FOR i IN 1 .. NumbersTab.COUNT LOOP
    DBMS_OUTPUT.PUT( NumbersTab(i) || ',' );
  END LOOP;
  DBMS_OUTPUT.PUT_LINE( '' );
END;
/

所有输出:

1,2,3,4,

db<>fiddle

© www.soinside.com 2019 - 2024. All rights reserved.