Передача динамич c Колонны в Pivot в Oracle - PullRequest
0 голосов
/ 26 марта 2020

Я новичок в oracle, я пытаюсь передать динамически сгенерированные имена столбцов в сводную в oracle, используя следующий запрос

DECLARE
   v_cols VARCHAR2(100);
   v_query VARCHAR2(4000);

BEGIN

    SELECT LISTAGG('''' ||product_code||'''',',') WITHIN GROUP (ORDER BY product_code) 
    INTO v_cols
    FROM (
        SELECT  DISTINCT product_code
        FROM pivot_test
        );

    v_query:='
      SELECT *
      FROM   (
              SELECT product_code,
                     quantity
              FROM   pivot_test) 
              PIVOT (sum(quantity) AS qunts 
              FOR product_code IN ('|| v_cols ||'));';

    EXECUTE IMMEDIATE v_query;
    --dbms_output.Put_line(v_cols); 
    --dbms_output.Put_line(v_query);   
END;

Сгенерированный столбец 'A', 'B ',' C ',' D 'и запрос, сгенерированный с использованием столбца Dynami c:

SELECT *
FROM   (
              SELECT 
                     product_code,
                     quantity
              FROM   pivot_test) PIVOT (sum(quantity) AS qunts FOR product_code IN ('A','B','C','D'));

Результат: Result

Когда я беру вышеупомянутый запрос и запускаю его отдельно, он работает правильно, но когда я использую EXECUTE IMMEDIATE v_query;, я получаю сообщение об ошибке

  ORA-00911: invalid character
  ORA-06512: at line 20

Я не знаю, что является причиной проблемы, может любой пожалуйста, укажите, что не так с этим динамическим c выполнением запроса

Значение, используемое для тестирования

CREATE TABLE pivot_test
  (
     id           NUMBER,
     customer_id  NUMBER,
     product_code VARCHAR2(5),
     quantity     NUMBER
  );

INSERT INTO pivot_test VALUES (1,1,'A',10);    
INSERT INTO pivot_test VALUES (2,1,'B',20);    
INSERT INTO pivot_test VALUES (3,1,'C',30);    
INSERT INTO pivot_test VALUES (4,2,'A',40);    
INSERT INTO pivot_test VALUES (5,2,'C',50);    
INSERT INTO pivot_test VALUES (6,3,'A',60);
INSERT INTO pivot_test VALUES (7,3,'B',70);
INSERT INTO pivot_test VALUES (8,3,'C',80);    
INSERT INTO pivot_test VALUES (9,3,'D',90);    
INSERT INTO pivot_test VALUES (10,4,'A',100);

COMMIT; 

1 Ответ

0 голосов
/ 26 марта 2020
  1. Для ошибки ORA-00911 необходимо удалить ;, добавленный в конец динамически сгенерированного v_query
  2. Для отображения выходных данных вы можете получить результаты в курсор. Весь блок может go в вашу динамику c SQL. Пример ниже:
set serveroutput on;

declare
   v_cols varchar2(100);
   v_query varchar2(4000);

begin

select listagg('''' ||product_code||'''',',') within group (order by product_code) into v_cols
from(
select  distinct product_code
 from pivot_test
);

v_query:='
declare
   cur_pivot_test   sys_refcursor;
   a    number;
   b    number;
   c    number;
   d    number;
begin
    open cur_pivot_test for
        select * from (select product_code, quantity from pivot_test) 
        pivot (sum (quantity)
        as qunts
        for product_code in ('|| v_cols ||'));

    fetch cur_pivot_Test into a, b, c, d;

    close cur_pivot_test;

    dbms_output.put_line (rpad(''A_QTY'',10) || '' | '' || rpad(''B_QTY'',10) || '' | '' || rpad(''C_QTY'',10) || '' | '' ||  rpad(''D_QTY'',10) );
    dbms_output.put_line (rpad(a,10) || '' | '' || rpad(b,10) || '' | '' || rpad(c,10) || '' | '' ||  rpad(d,10) );              

    end;
';

  execute immediate v_query;

end;


Выход:

A_QTY      | B_QTY      | C_QTY      | D_QTY     
210        | 90         | 160        | 90      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...