sql >> データベース >  >> RDS >> Oracle

`getclobval()`を使用してOracleプロシージャを実行中に`無効な文字エラーが発生しました`

    SQL> CREATE OR REPLACE PROCEDURE pivot (v_recordset OUT SYS_REFCURSOR)
      2  AS
      3     --v_recordset SYS_REFCURSOR;
      4     v_sql     LONG;
      5     v_cols_1  LONG;
      6     v_cols_2  CLOB;
      7  BEGIN
      8     SELECT LISTAGG ('''' || "level" || ''' AS "' || "level" || '"', ',')
      9               WITHIN GROUP (ORDER BY "level" DESC)
     10       INTO v_cols_1
     11       FROM (SELECT DISTINCT "level"
     12               FROM tempt);
     13
     14     SELECT DBMS_XMLGEN.CONVERT (
     15               RTRIM (
     16                  XMLAGG (XMLELEMENT (
     17                             e,
     18                                'MAX(CASE WHEN CATEGORY = '
     19                             || CHR (39)
     20                             || CATEGORY
     21                             || CHR (39)
     22                             || ' THEN '
     23                             || CHR (39)
     24                             || "level"
     25                             || CHR (39)
     26                             || ' END) AS '
     27                             || "level"
     28                             || '_'
     29                             || CATEGORY
     30                             || '',
     31                             ',')
     32                          ORDER BY 1 DESC).EXTRACT ('//text()').getclobval (),
     33                  ','))
     34       INTO v_cols_2
     35       FROM (SELECT DISTINCT "level", CATEGORY
     36               FROM tempt);
     37
     38     v_sql := 'SELECT "set", ' || v_cols_2 || '
     39       FROM
     40       (
     41        SELECT *
     42          FROM tempt
     43             PIVOT
     44             (
     45              MAX(value) FOR "level" IN ( ' || v_cols_1 || ' )
     46             )
     47            )
     48            GROUP BY "set"
     49            ORDER BY "set"';
     50     v_sql := REPLACE (v_sql, ''', CHR (39));
     51     DBMS_OUTPUT.PUT_LINE (v_sql);
     52
     53     OPEN v_recordset FOR v_sql;
     54  END pivot;
     55  /
    
    Procedure created.
    
    SQL>
    

    テスト:

    SQL> SET SERVEROUTPUT ON
    SQL> DECLARE
      2     l_rc  SYS_REFCURSOR;
      3  BEGIN
      4     pivot (l_rc);
      5  END;
      6  /
    SELECT "set", MAX(CASE WHEN CATEGORY = 'GHI' THEN 'Y' END) AS Y_GHI,MAX(CASE
    WHEN CATEGORY = 'ABC' THEN 'Y' END) AS Y_ABC,MAX(CASE WHEN CATEGORY = 'ABC' THEN
    'Z' END) AS Z_ABC,MAX(CASE WHEN CATEGORY = 'DEF' THEN 'Z' END) AS Z_DEF,MAX(CASE
    WHEN CATEGORY = 'IJK' THEN 'X' END) AS X_IJK,MAX(CASE WHEN CATEGORY = 'GHI' THEN
    'Z' END) AS Z_GHI,MAX(CASE WHEN CATEGORY = 'DEF' THEN 'X' END) AS X_DEF,MAX(CASE
    WHEN CATEGORY = 'ABC' THEN 'X' END) AS X_ABC,MAX(CASE WHEN CATEGORY = 'DEF' THEN
    'Y' END) AS Y_DEF
         FROM
         (
          SELECT *
            FROM tempt
    
    PIVOT
               (
                MAX(value) FOR "level" IN ( 'Z' AS "Z",'Y' AS
    "Y",'X' AS "X" )
               )
              )
              GROUP BY "set"
    
    ORDER BY "set"
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    結果のクエリを実行すると、次の結果が生成されます (抜粋):

    SQL> SELECT "set", MAX(CASE WHEN CATEGORY = 'GHI  <snip>
    ORY = 'DEF' THEN 'Z' END) AS Z_DEF,MAX(CASE WHEN  <snip>
    (CASE WHEN CATEGORY = 'ABC' THEN 'X' END) AS X_A  <snip>
      2       FROM
      3       (
      4        SELECT *
      5          FROM tempt
      6             PIVOT
      7             (
      8              MAX(value) FOR "level" IN ( 'Z'
      9             )
     10            )
     11            GROUP BY "set"
     12            ORDER BY "set"
     13  /
    
    s Y Y Z Z X Z X X Y
    - - - - - - - - - -
    A Y Y Z Z   Z X X Y
    B   Y Z Z X   X X Y
    C   Y Z Z     X X Y
    D Y Y Z Z   Z X X Y
    E   Y Z Z     X X Y
    
    SQL>
    

    追記言い忘れました :本当に、本当に本当に 二重引用符の下に小文字を使用して列に名前を付けるのは悪い考えです。




    1. MySQLのクエリのGROUPBY句は、場合によってのみ接続をクラッシュさせます

    2. UNIQUE-テーブルに一意の行を含める方法は?

    3. 非同期 JMS リスナーを初期化し、無限に実行させるための正しいアプローチ

    4. c#とmysql間のデータトラフィックを暗号化する