Ошибка в PL / SQL при использовании динамического PIVOT - PullRequest
0 голосов
/ 30 мая 2018

Я пытаюсь создать динамическую команду PIVOT, потому что я не знаю точное количество столбцов, которые понадобятся в предложении «in».Проблема в этом подходе заключается в том, что я получаю сообщение об ошибке после execute немедленного , где говорится, что типы данных несовместимы, даже если ожидаемые значения совпадают.Я также пытался использовать 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;
    /

Модель

enter image description here

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Как было указано в комментариях, неизвестная структура столбцов вашего курсора очень затруднит извлечение результатов в 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;
/ 
0 голосов
/ 30 мая 2018

Кроме того, вам не нужна таблица SCD_DOCUMENTO в вашем запросе.

Проблема в том, что вы извлекаете переменное число значений в structur: динамический запрос дает результат вколичество столбцов зависит от значений в ваших таблицах, поэтому вы не можете заранее знать, сколько столбцов будет иметь результат.

Таким образом, вы не сможете извлечь результат в фиксированное количество структурпотому что вы не знаете во время компиляции, сколько переменных вам нужно использовать, чтобы получить ваш результат.

...