说,我有以下查询:
select 1 foo, 2 bar, 3 baz from dual;
基本上,这个查询总是返回一行。我需要创建一个关联数组,其中之一:
arr('foo') = 1;
arr('bar') = 2;
arr('baz') = 3;
我知道结果集只有一行。我既不知道列数量也不知道列名称。
有什么想法吗?
感谢。
UPD:
我的一位朋友发现了一个优秀且优雅的XML解决方案:
SELECT
XMLTYPE(EXTRACT(VALUE(T), '/*') .GETSTRINGVAL()) .GETROOTELEMENT() NODE,
EXTRACTVALUE(COLUMN_VALUE, '/*') NODEVALUE
FROM
TABLE(XMLSEQUENCE(XMLTYPE((CURSOR
(
--this is the query that needs to be transformed
SELECT
*
FROM
some_table
WHERE some_table.id = 123
)
)) .EXTRACT('/ROWSET/ROW/*'))) T;
答案 0 :(得分:2)
这是一个简单的包,它从键值对表中填充关联数组。这很容易。
create or replace package dynaa as
procedure pop;
procedure print;
end;
/
create or replace package body dynaa as
type aa is table of number
index by varchar2(30);
this_aa aa;
procedure pop
is
begin
for r in ( select * from t42 )
loop
this_aa (r.id) := r.col1;
end loop;
end pop ;
procedure print
is
idx varchar2(30);
begin
idx := this_aa.first();
while idx is not null
loop
dbms_output.put_line(idx ||'='||this_aa(idx));
idx := this_aa.next(idx);
end loop;
end print;
end;
/
它的工作非常巧妙......
SQL> set serveroutput on
SQL>
SQL> exec dynaa.pop
PL/SQL procedure successfully completed.
SQL> exec dynaa.print
DAISY HEAD MAISIE=6969
FOX IN SOCKS=4242
MR KNOX=2323
PL/SQL procedure successfully completed.
SQL>
但是你想要的更复杂:在不知道查询投影的情况下动态填充数组。以下是一个非常简单的实现,如果有问题的表包含单行,它将起作用。它可以很容易地扩展到处理多行的表。
我们重载了POP()
程序:
procedure pop
( tabname user_tab_columns.table_name%type );
procedure pop
( tabname user_tab_columns.table_name%type );
is
n number;
begin
for r in ( select column_name
from user_tab_columns
where table_name = tabname)
loop
execute immediate 'select '||r.column_name||' from '||tabname into n;
this_aa (r.column_name) := n;
end loop;
end pop ;
所以,这也有效:
SQL> exec dynaa.pop('T23')
PL/SQL procedure successfully completed.
SQL>
SQL> exec dynaa.print
COL1=2323
COL2=4242
COL3=6969
PL/SQL procedure successfully completed.
SQL>
我并不太担心以如此笨拙的方式初始化阵列所带来的性能损失。鉴于记录保留在缓存中,这并不算太糟糕。如果你经常调用POP()
表示性能确实成为一个问题,那么你可能不应该首先使用关联数组:常规查找或结果集缓存是更好的选择。
答案 1 :(得分:1)
一个很简短的答案是使用DBMS_SQL
包查看旧式(Oracle 9之前版本)动态SQL。您可以使用DESCRIBE_COLUMNS
获取列的数量(和数据类型),并COLUMN_VALUE
为DESCRIBE_COLUMNS
返回的PL / SQL表中的每个条目单独获取每个列值。
之后,将一行转换为关联数组非常容易。