首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Oracle中的匿名表或VARRAY类型

Oracle中的匿名表或VARRAY类型
EN

Stack Overflow用户
提问于 2012-01-09 16:12:02
回答 3查看 25.8K关注 0票数 19

在Oracle中,我有时想创建像这样的构造

SELECT * FROM TABLE(STRINGS('a', 'b', 'c'))
SELECT * FROM TABLE(NUMBERS(1, 2, 3))

显然,我可以为上面的代码声明我自己的类型。我可以在TABLEVARRAY之间选择。例如:

CREATE TYPE STRINGS AS TABLE OF VARCHAR2(100);
CREATE TYPE NUMBERS AS VARRAY(100) OF NUMBER(10);

在这种情况下,另一种解决方案是编写如下内容

SELECT 'a' FROM DUAL UNION ALL
SELECT 'b' FROM DUAL UNION ALL
SELECT 'c' FROM DUAL

但我可能有更复杂的示例,在这些示例中我确实需要TABLE / VARRAY类型。那么,如果我的SQL运行在一个未知的系统上,我不能创建类型,因为我可能没有必要的授权,那该怎么办呢?

所以我的问题是:知道在任何实例上可用的“匿名”TABLE / VARRAY类型吗?类似Postgres / H2 /HSQLDB的简单ARRAY类型?

SQL :我主要从运行这个,如果这是相关的话。不需要向我解释PL/SQL,我实际上只是在寻找匿名SQL数组类型(即“匿名”独立存储类型)。如果它们根本不存在,答案是否定的

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-09 18:20:35

SQL表和varray类型

用户APC here给出了一个有趣的解决方案。对于这个问题的未来读者来说,看到这个查询提供了我真正感兴趣的内容可能会很有趣:

select coll_type, elem_type_name, type_name, length, upper_bound
from all_coll_types
where owner = 'SYS'
and elem_type_name IN ('VARCHAR2', 'NUMBER')
order by coll_type, elem_type_name, type_name;

导致(在Oracle 11g中):

+-------------+--------------+----------------------+------+-----------+
|COLL_TYPE    |ELEM_TYPE_NAME|TYPE_NAME             |LENGTH|UPPER_BOUND|
+-------------+--------------+----------------------+------+-----------+
|TABLE        |NUMBER        |KU$_OBJNUMSET         |{null}|     {null}|
|TABLE        |NUMBER        |KU$_XMLCOLSET_T       |{null}|     {null}|
|TABLE        |NUMBER        |ORA_MINING_NUMBER_NT  |{null}|     {null}|
|TABLE        |VARCHAR2      |DBMS_AW$_COLUMNLIST_T |   100|     {null}|
|TABLE        |VARCHAR2      |DBMS_DEBUG_VC2COLL    |  1000|     {null}|
|TABLE        |VARCHAR2      |HSBLKNAMLST           |    30|     {null}|
|TABLE        |VARCHAR2      |KU$_VCNT              |  4000|     {null}|
|TABLE        |VARCHAR2      |ORA_MINING_VARCHAR2_NT|  4000|     {null}|
|VARYING ARRAY|NUMBER        |AWRRPT_NUM_ARY        |{null}|         30|
|VARYING ARRAY|NUMBER        |JDM_NUM_VALS          |{null}|        999|
|VARYING ARRAY|NUMBER        |ODCIGRANULELIST       |{null}|      65535|
|VARYING ARRAY|NUMBER        |ODCINUMBERLIST        |{null}|      32767|
|VARYING ARRAY|NUMBER        |SQL_OBJECTS           |{null}|       2000|
|VARYING ARRAY|NUMBER        |TABLESPACE_LIST       |{null}|      64000|
|VARYING ARRAY|VARCHAR2      |AQ$_JMS_NAMEARRAY     |   200|       1024|
|VARYING ARRAY|VARCHAR2      |AQ$_MIDARRAY          |    32|       1024|
|VARYING ARRAY|VARCHAR2      |AWRRPT_VCH_ARY        |    80|         30|
|VARYING ARRAY|VARCHAR2      |DBMSOUTPUT_LINESARRAY | 32767| 2147483647|
|VARYING ARRAY|VARCHAR2      |DBMS_XS_ROLELIST      |  1024|       4096|
|VARYING ARRAY|VARCHAR2      |FLASHBACKTBLIST       |    30|        100|
|VARYING ARRAY|VARCHAR2      |HSBLKVALARY           |  4000|        250|
|VARYING ARRAY|VARCHAR2      |JDM_ATTR_NAMES        |    60|        999|
|VARYING ARRAY|VARCHAR2      |JDM_STR_VALS          |  4000|        999|
|VARYING ARRAY|VARCHAR2      |KU$_DROPCOLLIST       |  4000|       1000|
|VARYING ARRAY|VARCHAR2      |KUPC$_LOBPIECES       |  4000|       4000|
|VARYING ARRAY|VARCHAR2      |ODCIRIDLIST           |  5072|      32767|
|VARYING ARRAY|VARCHAR2      |ODCIVARCHAR2LIST      |  4000|      32767|
|VARYING ARRAY|VARCHAR2      |RE$NAME_ARRAY         |    30|       1024|
|VARYING ARRAY|VARCHAR2      |RE$RULE_LIST          |    65|       1024|
|VARYING ARRAY|VARCHAR2      |SQLPROF_ATTR          |   500|       2000|
|VARYING ARRAY|VARCHAR2      |TXNAME_ARRAY          |   256|        100|
+-------------+--------------+----------------------+------+-----------+

看起来ORA_MINING_NUMBER_NTORA_MINING_VARCHAR2_NT将会是我需求的最佳组合。

PL/SQL索引数组类型

如果使用Oracle12c和PL/SQL,还可以使用任何DBMS_SQL类型,这些类型可以使用TABLE(..)构造函数取消嵌套。这里有:

  • DBMS_SQL.CLOB_TABLE
  • DBMS_SQL.BINARY_FLOAT_TABLE
  • DBMS_SQL.BINARY_DOUBLE_TABLE
  • DBMS_SQL.BLOB_TABLE
  • DBMS_SQL.BFILE_TABLE
  • DBMS_SQL.DATE_TABLE
  • DBMS_SQL.NUMBER_TABLE
  • DBMS_SQL.UROWID_TABLE
  • DBMS_SQL.VARCHAR2_TABLE
  • DBMS_SQL.TIME_TABLE
  • DBMS_SQL.TIME_WITH_TIME_ZONE_TABLE
  • DBMS_SQL.TIMESTAMP_TABLE
  • DBMS_SQL.TIMESTAMP_WITH_LTZ_TABLE
  • DBMS_SQL.TIMESTAMP_WITH_TIME_ZONE_TABLE
  • DBMS_SQL.INTERVAL_DAY_TO_SECOND_TABLE
  • DBMS_SQL.INTERVAL_YEAR_TO_MONTH_TABLE
票数 18
EN

Stack Overflow用户

发布于 2012-01-09 17:45:12

如果您不怕显式引用SYS模式,这里有几个。下面是一些我经常使用的代码( odcivarchar2list不是很常用,因为它占用大量内存:对于字符串,我更喜欢dbms_debug_vc2coll)。

SQL> desc sys.odcinumberlist
 sys.odcinumberlist VARRAY(32767) OF NUMBER

SQL> desc sys.odcivarchar2list
 sys.odcivarchar2list VARRAY(32767) OF VARCHAR2(4000)

SQL> desc sys.ODCIDATELIST
 sys.ODCIDATELIST VARRAY(32767) OF DATE

SQL> desc sys.dbms_debug_vc2coll
 sys.dbms_debug_vc2coll TABLE OF VARCHAR2(1000)

SQL> 

但是,如果这些不足以满足您的需求,请运行以下查询以查找更多:

select type_name
       , owner
from all_types
where typecode = 'COLLECTION'
and owner != user
/

当然,这个结果在不同的数据库中会有所不同。例如,我的数据库上的许多集合都归XDB所有,并不是每个系统都会安装XDB。从9iR2 (甚至更早)开始,我在本答案顶部列出的四个数据库应该可以在每个数据库中使用,尽管它们并不总是在早期版本中记录。

“请注意,ALL_COLL_TYPES似乎是查找适当类型的更好的字典视图”

这是一个很好的观点。我们还可以对COLL_TYPE进行过滤,以筛选出VARRAY。该视图是在10g中引入的,而ALL_TYPES在9i中可用。与大多数Oracle一样,版本越晚,它的功能就越多。

票数 20
EN

Stack Overflow用户

发布于 2012-01-09 16:40:38

您的问题非常笼统--基本上您可以在匿名PL/TABLE块中使用这些(VARARRAY / TABLE)而不使用显式CREATE TYPE,如下所示:

DECLARE
    TYPE genres IS VARRAY(4) OF book_genre.genre_name%TYPE;
    Fiction_genres genres;
    TYPE phone_no_tab IS VARRAY(6) OF VARCHAR2(20) ;
    phone_nos phone_no_tab;
BEGIN
    fiction_genres := genres('MYSTERY','SUSPENSE', 'ROMANCE','HORROR');
    phone_nos := phone_no_tab();
    phone_nos.EXTEND(2);
    phone_nos(1) := '0117 942 2508';
END;

或者像这样

declare

  TYPE auftrag_table_typ IS TABLE OF auftrag%ROWTYPE
          INDEX BY BINARY_INTEGER;

  auftrag_table auftrag_table_typ;

  v_index BINARY_INTEGER;

begin

  v_index := auftrag_table.first;

  while v_index is not NULL loop

    // do something with auftrag_table(v_index)

    v_index := auftrag_table.next (v_index);

  end loop;

end; 

有关Oracle参考,请参阅http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/composites.htm -根据这一点,任何这样的VARARRAY和/或TABLE都需要是DECLAREd或通过CREATE TYPE创建的,因此AFAIK没有“匿名VARARRAY / TABLE”这样的东西。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8785459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档