我试图创建一个动态PIVOT命令,因为我不知道" in"中需要的确切列数。条款。这种方法的问题是我在执行 立即之后收到错误,其中表示即使预期值匹配,数据类型也不一致。我也尝试使用sys_refcursor但发生了同样的错误。它可能是什么?
set serveroutput on;
declare
storage_var clob;
storage_query clob;
type table_model is table of varchar2(100) index by pls_integer;
tabl table_model;
begin
SELECT DISTINCT LISTAGG('''' || scd_local.descricao || '''',',')
WITHIN GROUP (ORDER BY scd_local.descricao) INTO storage_var FROM scd_local;
--Creates a list of values to to be used in the pivot command
storage_query := 'select * from (select doc.nome, loc.descricao
from scd_documento doc, scd_local_doc doc_loc, scd_local loc
where doc.nome = doc_loc.id_doc and loc.id = doc_loc.id_local
order by 1, 2)
pivot
(max(descricao) for descricao in ( ' || storage_var || ' ))';
dbms_output.put_line(storage_query);
execute immediate storage_query bulk collect into tabl;
--Gives an error: "inconsistent datatypes: expected %s got %s"
for i in 1.. tabl.count
loop
dbms_output.put_line(tabl(i));
end loop;
end;
/
模型
答案 0 :(得分:2)
另外,您不需要在查询中使用表格SCD_DOCUMENTO
。
问题在于您将一个可变数量的值提取到结构中:动态查询给出的结果是列数取决于表中的值,因此您无法预先知道有多少列结果会有。
这样,您无法将结果提取到固定数量的结构中,因为您在编译时不知道需要使用多少变量来获取结果。
答案 1 :(得分:0)
正如评论中指出的那样,游标的未知列结构将使得将结果提取到PL / SQL变得非常困难。
但是,如果您真正要做的就是通过DBMS_OUTPUT
将结果发送回客户端,您实际上可以使用DBMS_OUTPUT.RETURN_RESULTS
执行此操作。
以下是PL / SQL块的修改版本,它打印来自DBA_OBJECTS
的用户和对象类型的交叉表,每个单元格显示给定用户拥有的给定类型的对象数。
declare
storage_var clob;
storage_query clob;
l_ref_cur SYS_REFCURSOR;
begin
SELECT LISTAGG('''' || o.object_type || '''',',')
WITHIN GROUP ( ORDER BY o.object_type)
INTO storage_var
FROM ( SELECT DISTINCT OBJECT_TYPE FROM dba_objects ) o;
storage_query := 'select *
from ( SELECT owner, object_type FROM dba_objects ) o
pivot
(count(*) for object_type in (' || storage_var || '))
order by 1';
dbms_output.put_line(storage_query);
OPEN l_ref_cur FOR storage_query;
dbms_sql.return_result(l_ref_cur);
end;
/