Oracle PLSQLは、[閉じ]でグループ化する動的sqlなしでピボットを選択します。

StackOverflow https://stackoverflow.com/questions/4699332

質問

応答する人には、11G R2 Oracle DBMSでピボットオプションを使用してSelect Functionを使用したいと考えています。私たちのクエリは次のようなものです。

select * from
(SELECT o.ship_to_customer_no, ol.item_no,ol.amount
  FROM t_order o, t_order_line ol
 WHERE o.NO = ol.order_no and ol.item_no in (select distinct(item_no) from t_order_line))
  pivot --xml 
(  SUM(amount) FOR item_no IN ( select distinct(item_no) as item_no_ from t_order_line));

ご覧のとおり、XMLはコメントアウトされています。PivotXMLとして実行すると、XML形式で正しい出力が得られますが、データをフォーマットのピボットデータとして取得する必要がありますが、この文はエラーをスローします。ORA-00936:式が欠落しています

解決策やアイデアは歓迎されます、

よろしくお願いします

--------------ダーティですが、作業プロセスは以下です--------------------------------------------------------------------------

17.01.2011までに手順を更新しました16:39 GMT:

 PROCEDURE pr_pivot_item_by_ship_to (
      p_location_code             IN       t_customer.location_code%TYPE,
      p_customer_price_group      IN       t_customer.customer_price_group%TYPE,
      p_shipment_date             IN       t_order.shipment_date%TYPE,
      p_fasdat_status             IN       t_order.fasdat_status%TYPE,
      p_order_type                IN       t_order.order_type%TYPE,
      cur_pivot_item_by_ship_to   OUT      sys_refcursor
   )
   IS
      v_sql            VARCHAR2 (15000);
      v_pivot_items    VARCHAR2 (15000) := '';
      v_query_items    VARCHAR2 (15000) := '';
      v_pivot_orders   VARCHAR2 (15000) := '';
      v_continue       INT              := 0;
   BEGIN
      /*GET ORDER NUMBERS*/
      FOR cur_order_loop IN (SELECT DISTINCT (o.NO) AS order_no
                                        FROM t_order o,
                                             vw_customer_with_ship_to_info wwc
                                       WHERE wwc.customer_price_group =
                                                        p_customer_price_group
                                         AND wwc.location_code =
                                                               p_location_code
                                         AND o.shipment_date = p_shipment_date
                                         AND o.fasdat_status = p_fasdat_status
                                         AND o.order_type = p_order_type
                                         AND wwc.NO = o.customer_no)
      LOOP
         v_pivot_orders :=
                ''',''' || TO_CHAR (cur_order_loop.order_no)
                || v_pivot_orders;
         v_pivot_orders := LTRIM (v_pivot_orders, ''',''');
      END LOOP;

      /*USE ORDER NUMBERS TO FIND ITEMS TO PIVOT BY SHIPMENT PLACE*/
      FOR cur_loop IN
         (SELECT DISTINCT (ol.item_no) AS item_no,
                          REPLACE
                             (REPLACE (SUBSTR (i.description, 1, 20), '''',
                                       ''),
                              '"',
                              ' inch'
                             ) AS description
                     FROM t_order_line ol, t_item i
                    WHERE ol.item_no = i.NO
                      AND ol.order_no IN (
                             SELECT DISTINCT (o.NO) AS order_no
                                        FROM t_order o,
                                             vw_customer_with_ship_to_info wwc
                                       WHERE wwc.customer_price_group =
                                                        p_customer_price_group
                                         AND wwc.location_code =
                                                               p_location_code
                                         AND o.shipment_date = p_shipment_date
                                         AND o.fasdat_status = p_fasdat_status
                                         AND o.order_type = p_order_type
                                         AND wwc.NO = o.customer_no))
      LOOP
         v_query_items := ',''' || cur_loop.item_no || '''' || v_query_items;
         v_pivot_items :=
               ','''
            || cur_loop.item_no
            || ''' as "ad_'
            || cur_loop.description
            || '"'
            || v_pivot_items;
      END LOOP;

      v_query_items := LTRIM (v_query_items, ',');
      v_pivot_items := LTRIM (v_pivot_items, ',');
      v_sql :=
            'select * from
       (SELECT wwc.ship_to_customer_no||''-''|| wwc.ship_to_customer_name as "Müst. Adi ('
         || p_order_type
         || ')", ol.item_no,ol.amount
         FROM t_order o, t_order_line ol,vw_customer_with_ship_to_info wwc
        WHERE o.NO = ol.order_no
        and wwc.no = o.customer_no
        and ol.order_no in (
        (SELECT DISTINCT (o.NO) AS order_no
                                            FROM t_order o,
                                                 vw_customer_with_ship_to_info wwc
                                           WHERE wwc.customer_price_group ='''
         || p_customer_price_group
         || '''
                                             AND wwc.location_code =
                                                                   '''
         || p_location_code
         || '''
                                            AND o.shipment_date = '''
         || p_shipment_date
         || '''

                                             AND o.fasdat_status = '
         || p_fasdat_status
         || '
                                             AND o.order_type = '''
         || p_order_type
         || '''
                                             AND wwc.NO = o.customer_no)
         )
        and OL.ITEM_NO in ('
         || v_query_items
         || ')
        )
         pivot
       (  SUM(amount) FOR item_no IN ('
         || v_query_items                                      --v_pivot_items
         || '))';

      --DBMS_OUTPUT.put_line ('TSQL ' || v_sql);
       --      OPEN cur_pivot_item_by_ship_to FOR
        --         SELECT v_sql
        --           FROM DUAL;
      BEGIN
         OPEN cur_pivot_item_by_ship_to FOR v_sql;
      EXCEPTION
         WHEN NO_DATA_FOUND
         THEN
            NULL;
         WHEN OTHERS
         THEN
            IF SQLCODE = -936
            THEN
               NULL;
            ELSE
               pck_helper.pr_log_error
                                      (SQLCODE,
                                          'p_shipment_date:'
                                       || p_shipment_date
                                       || ','
                                       || 'cur_pivot_item_by_ship_to err. :'
                                       || SQLERRM,
                                       'pr_pivot_item_by_ship_to'
                                      );
            END IF;
      END;
   EXCEPTION
      WHEN NO_DATA_FOUND
      THEN
         NULL;
      WHEN OTHERS
      THEN
         pck_helper.pr_log_error (SQLCODE,
                                     'p_shipment_date:'
                                  || p_shipment_date
                                  || ','
                                  || SQLERRM,
                             'pr_pivot_item_by_ship_to'
                                 );
   END pr_pivot_item_by_ship_to;
END pkg_report;
役に立ちましたか?

解決 2

2011年17.01.2011で編集された手順は汚れていますが、機能しているため、ループカーソルは変更され、より良いERRが変更されます。ダイナミックSQLの処理(現在はありません)は、時間が取れたときに改善しようとします。皆様のご協力ありがとうございます。

他のヒント

私は今私に利用できるOracle11インスタンスを持っていません(私は今利用できます(PIVOT Oracle 11に新しいです)ので、私は推測することしかできません。私の推測はそれです -- その後、すべてをコメントすることになりました pivot, 、そして、Oracleはあなたに「失われた式」エラーを与えました。 pivot. 。コメントしてみましたか xml それを囲むことによって /**/ 置く代わりに -- その前に?

たとえば、Javaからこのクエリを実行している場合、次の文字列でSQLを実行しようとした場合、「式が欠落している」エラーが発生することを期待します。

String sql =
  "select * from (SELECT o.ship_to_customer_no, ol.item_no,ol.amount " +
  "FROM t_order o, t_order_line ol " +
  "WHERE o.NO = ol.order_no and ol.item_no in (select distinct(item_no) from t_order_line)) " + 
  "pivot --xml " +
  "( SUM(amount) FOR item_no IN ( select distinct(item_no) as item_no_ from t_order_line))";

このSQL文字列は1つの行に連結されるため、 -- の前に xml オラクルはクエリの後のすべてを無視します。

編集: :あなたが追加した手順では、私に関係するのはこの部分です(省略):

v_sql := 'begin
           select * from ...;
          end;';

open DENEME for
select v_sql from dual;

なぜあなたが使用しているのかわかりません BEGINEND 以内に v_sql. 。それらを削除してみてください。

また、SQLステートメント文字列に後続のセミコロンを残さないように注意してください。以下は ORA-00911: invalid character executeを即時またはそのように実行して実行しようとする場合のエラー:

v_sql := 'select * from dual;'; /* note the semicolon inside the string */

しかし、以下は大丈夫です:

v_sql := 'select * from dual';

最後に、このSQLクエリの結果を文字列としてではなく、このSQLクエリの結果を返したいと思うようです。あなたの交換 open DENEME for ... 以下の声明はあなたが望むことをする必要があります:

open DENEME for v_sql;

編集2: :手順では、dbms_output.put_lineへのコメントアウトコールがあります。ここで生成されたSQLが正しいことを確認しましたか?特に、形成に使用される値はどれもないと確信していますか v_query_itemsv_pivot_items 持ってる ' それらのキャラクター?

使用に問題がある可能性があります PIVOT 動的SQLを使用。ここでOracle 11にアクセスできないので、私は知りません。 SQLをはるかに小さなクエリに簡素化すると、まだエラーが発生しますか? PIVOT 初期化?言い換えれば、シンプルを見つけてください PIVOT 動作するクエリ(たとえば、SQL開発者やそのようなもので正常に実行できます)、次のような手順を作成し、データを取得するかどうかを確認してください。

CREATE OR REPLACE PROCEDURE dynamic_pivot_test(
  results OUT SYS_REFCURSOR
)
AS
BEGIN
  OPEN results FOR 'SELECT ...'; /* put the PIVOT query here. */
END;
/
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top