Oracle 在 SQL 中访问 varray 元素

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

我正在研究 Oracle 中的数组支持,并遇到了有关 SQL 查询中数组访问的障碍。我正在使用以下架构:

create type smallintarray as varray(10) of number(3,0);
create table tbl (
   id number(19,0) not null,
   the_array smallintarray,
   primary key (id)
);

我想做的是获取 id 和第一个元素,即数组的索引 1 处的元素。在 PostgreSQL 中我可以写

select id, the_array[1] from tbl t
但我不知道如何在 Oracle 中做到这一点。我读到,通过索引进行数组访问只能在 PL/SQL 中进行,如果我可以返回一个“修饰游标”以通过 JDBC 实现相同的结果,那就太好了,但我不知道这是否可能。

DECLARE
 c1   SYS_REFCURSOR;
 varr smallintarray2;
BEGIN
  OPEN c1 FOR SELECT t.id, t.THE_ARRAY from tbl t;
  -- SELECT t.THE_ARRAY INTO varr FROM table_with_enum_arrays2 t;
  -- return a "decorated cursor" with varr(1) at select item position 1
  dbms_sql.return_result(c1);
END;
oracle
3个回答
2
投票

您可以使用简单的 SQL 来完成此操作;它不漂亮,但确实有效。您希望 Oracle 有语法来向程序员隐藏这一点(也许确实如此,至少在最新版本中;我仍然停留在 12.2)。

select t.id, q.array_element
from   tbl t cross apply 
       ( select column_value as array_element,
                rownum       as ord
         from   table(the_array)
       ) q
where  ord = 1
;

编辑 如果通过

table
运算符生成元素的顺序是一个问题,您可以执行类似的操作(在 Oracle 12.1 及更高版本中;否则该函数不能成为查询本身的一部分,但可以是自己定义):

with
  function select_element(arr smallintarray, i integer)
    return number
    as
    begin
      return arr(i);
    end;
select id, select_element(the_array, 1) as the_array_1
from   tbl
/

1
投票

首先,请不要在生产中这样做。使用表而不是在表中存储数组。

回答你的问题是使用列作为表源

SELECT t.id, ta.*
  from tbl t,
       table(t.THE_ARRAY) ta
 order by column_value
--  offset 1 row -- in case if sometime you'll need to skip a row
fetch first 1 row only;

UPD:至于对数组进行排序,我只能说使用 2asc/desc" 参数为我提供了预期的结果 - 它已按升序或降序排序。

UPD2:找到了一个很酷的链接来描述性能可能发生的问题


0
投票

您可以使用名为

SYS_OP_CEG
的未记录函数在 Oracle SQL 中执行此操作:

SELECT SYS_OP_CEG
       ( sys.odcivarchar2list('Dave','Dee','Dozy','Beaky','Mick','Titch')
       , 3 ) AS third_item
FROM   dual;

SYS_OP_CEG
采用一个变量数组和一个从一开始的索引作为参数。上面的示例使用
varchar2
的变量并打印
Dozy
,这是第三个元素。

是的,它不如 PostgreSQL 简单。

P.S:我刚刚使用 Oracle 19 进行了测试,但预计它可以与 Oracle 9.2 及更高版本一起使用。

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