Oracle EXECUTE IMMEDIATE不显示输出

zysjyyx4  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(159)

我已经写了下面的透视查询,但它不显示任何输出行。它只是显示PL/SQL过程成功完成。

DECLARE 
    expression CLOB;
BEGIN 

SELECT LISTAGG('''' || MONTH || ''' AS "' || MONTH || '"', ', ')
    INTO expression
    FROM (SELECT DISTINCT MONTH FROM USER_AGREEMENT);

expression:= 'SELECT *
 FROM (
        SELECT AGGREMENTID, MONTH, AMOUNT
        FROM USER_AGREEMENT
    )
    PIVOT (
        SUM(AMOUNT)
        FOR MONTH IN (' || expression ||')
    )';
    EXECUTE IMMEDIATE expression;
END;

我尝试使用DBMS_OUTPUT.put_line(expression);但它不起作用

brccelvz

brccelvz1#

EXECUTE IMMEDIATE执行一个语句;它不显示任何内容。
如果你想显示一些东西,那么你需要使用DBMS_OUTPUT并循环遍历语句中的值:

DECLARE 
  expression CLOB;
  cur        SYS_REFCURSOR;
  id         USER_AGREEMENT.AGGREMENTID%TYPE;
  amount1    USER_AGREEMENT.AMOUNT%TYPE;
  amount2    USER_AGREEMENT.AMOUNT%TYPE;
BEGIN 
  SELECT EMPTY_CLOB()
         || 'SELECT *
             FROM (
               SELECT AGGREMENTID, MONTH, AMOUNT
               FROM USER_AGREEMENT
             )
             PIVOT (
               SUM(AMOUNT)
               FOR MONTH IN ('
         || LISTAGG('''' || MONTH || ''' AS "' || MONTH || '"', ', ')
         || '))'
  INTO   expression
  FROM   (SELECT DISTINCT MONTH FROM USER_AGREEMENT);

  OPEN cur FOR expression;

  LOOP
    FETCH cur INTO id, amount1, amount2;
    EXIT WHEN cur%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(id || ', ' || amount1 || ', ' || amount2);
  END LOOP;
END;
/

或:

DECLARE 
  TYPE id_tab     IS TABLE OF USER_AGREEMENT.AGGREMENTID%TYPE;
  TYPE amount_tab IS TABLE OF USER_AGREEMENT.AMOUNT%TYPE;
  expression CLOB;
  ids        id_tab;
  amount1s   amount_tab;
  amount2s   amount_tab;
BEGIN 
  SELECT EMPTY_CLOB()
         || 'SELECT *
             FROM (
               SELECT AGGREMENTID, MONTH, AMOUNT
               FROM USER_AGREEMENT
             )
             PIVOT (
               SUM(AMOUNT)
               FOR MONTH IN ('
         || LISTAGG('''' || MONTH || ''' AS "' || MONTH || '"', ', ')
         || '))'
  INTO   expression
  FROM   (SELECT DISTINCT MONTH FROM USER_AGREEMENT);

  EXECUTE IMMEDIATE expression
    BULK COLLECT INTO ids, amount1s, amount2s;

  FOR i IN 1 .. ids.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE(ids(i) || ', ' || amount1s(i) || ', ' || amount2s(i));
  END LOOP;
END;
/

其中,对于样本数据:

CREATE TABLE user_agreement (aggrementid, month, amount) AS
SELECT 1, 'January',  LEVEL FROM DUAL CONNECT BY LEVEL <= 3 UNION ALL
SELECT 1, 'February', LEVEL FROM DUAL CONNECT BY LEVEL <= 2 UNION ALL
SELECT 2, 'January',  LEVEL FROM DUAL CONNECT BY LEVEL <= 5;

两个输出:

1, 6, 3
2, 15,

但是,如果你知道只有12个不同的月份,那么你可能不需要动态查询:

SELECT *
FROM (
  SELECT AGGREMENTID, MONTH, AMOUNT
  FROM USER_AGREEMENT
)
PIVOT (
  SUM(AMOUNT)
  FOR MONTH IN (
    'January'   AS January,
    'February'  AS February,
    'March'     AS March,
    'April'     AS April,
    'May'       AS May,
    'June'      AS June,
    'July'      AS July,
    'August'    AS August,
    'September' AS September,
    'October'   AS October,
    'November'  AS November,
    'December'  AS December
  )
)

其输出:
| AGGREMENTID|一月|二月|三月|四月|可以|六月|七月|八月|九月|十月|十一月|十二月|
| --|--|--|--|--|--|--|--|--|--|--|--|--|
| 1 | 6 | 3 |* 空 ||||||||||
| 2 | 15 |
|||||||||| 空 *|
fiddle

相关问题