如何从 Oracle 中的值列表中进行选择

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

我指的是这个

stackoverflow
答案:

如何从 SQL Server 中的值列表中进行选择

如何在 Oracle 中完成类似的事情?

我已经在本页上看到了使用

UNION
的其他答案,尽管这种方法在技术上可行,但它不是我想在我的案例中使用的方法。

所以我想继续使用或多或少看起来像逗号分隔的值列表的语法。

更新关于

create type table
答案

我有一张桌子:

CREATE TABLE BOOK
(   "BOOK_ID" NUMBER(38,0)
)

我使用此脚本,但它不会向

BOOK
表插入任何行:

create type number_tab is table of number;

INSERT INTO BOOK (
    BOOK_ID
)
SELECT A.NOTEBOOK_ID FROM
    (select column_value AS NOTEBOOK_ID from table (number_tab(1,2,3,4,5,6))) A
;

脚本输出:

TYPE number_tab compiled
Warning: execution completed with warning

但是如果我使用此脚本,它确实会向

BOOK
表插入新行:

INSERT INTO BOOK (
    BOOK_ID
)
SELECT A.NOTEBOOK_ID FROM
    (SELECT (LEVEL-1)+1 AS NOTEBOOK_ID FROM DUAL CONNECT BY LEVEL<=6) A
;
sql oracle select oracle11g
8个回答
97
投票

您不需要创建任何存储类型,就可以评估Oracle的内置集合类型。

select distinct column_value from table(sys.odcinumberlist(1,1,2,3,3,4,4,5))

72
投票

如果您正在寻求转换逗号分隔的值列表:

select column_value 
from table(sys.dbms_debug_vc2coll('One', 'Two', 'Three', 'Four'));

-- Or

select column_value 
from table(sys.dbms_debug_vc2coll(1,2,3,4));

如果您希望转换逗号分隔值的字符串,那么我会推荐 Justin Cave 的正则表达式 SQL 解决方案。


14
投票

从Oracle 12.2开始,不需要

TABLE
函数,可以直接从内置集合中选择。

SQL> select * FROM sys.odcinumberlist(5,2,6,3,78);

COLUMN_VALUE
------------
           5
           2
           6
           3
          78

SQL> select * FROM sys.odcivarchar2list('A','B','C','D');

COLUMN_VALUE
------------
A
B
C
D

8
投票

有多种方法可以获取逗号分隔的列表并将其解析为多行数据。在 SQL 中

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2    select '1,2,3,a,b,c,d' str from dual
  3  )
  4   select regexp_substr(str,'[^,]+',1,level) element
  5     from x
  6* connect by level <= length(regexp_replace(str,'[^,]+')) + 1
SQL> /

ELEMENT
----------------------------------------------------
1
2
3
a
b
c
d

7 rows selected.

或者在 PL/SQL 中

SQL> create type str_tbl is table of varchar2(100);
  2  /

Type created.

SQL> create or replace function parse_list( p_list in varchar2 )
  2    return str_tbl
  3    pipelined
  4  is
  5  begin
  6    for x in (select regexp_substr( p_list, '[^,]', 1, level ) element
  7                from dual
  8             connect by level <= length( regexp_replace( p_list, '[^,]+')) + 1)
  9    loop
 10      pipe row( x.element );
 11    end loop
 12    return;
 13  end;
 14
 15  /

Function created.

SQL> select *
  2    from table( parse_list( 'a,b,c,1,2,3,d,e,foo' ));

COLUMN_VALUE
--------------------------------------------------------------------------------
a
b
c
1
2
3
d
e
f

9 rows selected.

6
投票

你可以这样做:

create type number_tab is table of number;

select * from table (number_tab(1,2,3,4,5,6));

Oracle 将该列命名为 COLUMN_VALUE,因此这也有效:

select column_value from table (number_tab(1,2,3,4,5,6));

4
投票

嗨,使用 XML-Table 的字符串也是可能的

SELECT trim(COLUMN_VALUE) str FROM xmltable(('"'||REPLACE('a1, b2, a2, c1', ',', '","')||'"'));

0
投票

[已弃用] - 只是为了添加操作, 您的第二个代码的问题似乎是您没有定义“number_tab”类型。

如:

CREATE type number_tab is table of number;

SELECT a.notebook_id FROM (
SELECT column_value AS notebook_id FROM table (number_tab(1,2,3,4,5,6) )  ) a; 


INSERT INTO BOOK (  BOOK_ID )
SELECT a.notebook_id FROM (
SELECT column_value AS notebook_id FROM table (number_tab(1,2,3,4,5,6) )  ) a;

DROP type number_tab ; 

抱歉,我无法重现您的错误,您能否向我们发送所使用的 oracle 版本以及用于第一个实例的过程的相同代码?这可能会有所帮助。祝一切顺利。


0
投票

Oracle Database 23ai 支持表值构造函数。因此,从这个版本开始,您可以执行以下操作:

select * from (
  values ( 1 ), ( 2 ), ( 3 ), ( 4 ), ( 5 ), ( 6 ) 
) t ( id );

        ID
----------
         1
         2
         3
         4
         5
         6
© www.soinside.com 2019 - 2024. All rights reserved.