Domanda

A chi può rispondere, Vorremmo utilizzare la funzione selezionare l'opzione PIVOT con a 11g r2 DBMS Oracle. La nostra domanda è come:

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));

Come si può vedere, XML è commentata, se correre come XML PIVOT dà l'uscita corretta in formato XML, ma sono necessari per ottenere i dati come dati non formattati perno, ma questa frase getta errore: ORA-00936: l'espressione mancante

Tutte le risoluzioni o le idee sarebbe il benvenuto,

Con i migliori saluti

------------- sporco ma proc di lavoro è al di sotto ------------------------

aggiornato la procedura da 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;
È stato utile?

Soluzione 2

la procedura modificata il 17.01.2011 è sporca, ma di lavoro, looping cursori dovrebbe cambiare, meglio err. la gestione per l'SQL dinamico (attualmente secondo a nessuno), cercherà di migliorarlo, quando ho tempo. Grazie a tutti per il vostro aiuto.

Altri suggerimenti

Non ho un'istanza Oracle 11 a disposizione per me ora (PIVOT è nuovo in Oracle 11) in modo che posso solo speculare. La mia ipotesi è che il -- ha finito per commentare tutto ciò dopo la pivot, e Oracle vi ha dato un errore di 'mancante espressione' perché si aspettava di trovare qualcosa dopo pivot. Hai provato commentando xml circondandolo con /* e */ invece di mettere -- prima di esso?

Se si stesse eseguendo questa query da Java, per esempio, quindi mi aspetto di ottenere un errore di 'mancante espressione' se si è tentato di eseguire il codice SQL nella seguente stringa:

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))";

Poiché questa stringa SQL viene concatenato in una sola linea, il -- davanti xml causerà Oracle a ignorare tutto nella query dopo di esso.

Modifica : Nella procedura si è aggiunto, ciò che mi preoccupa è questa parte (abbreviato):

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

open DENEME for
select v_sql from dual;

Non capisco il motivo per cui si sta utilizzando BEGIN e END all'interno v_sql. Provare a rimuoverli.

Inoltre, fare attenzione a non lasciare il punto e virgola finale nella stringa SQL. Di seguito vi darà un errore ORA-00911: invalid character se si tenta di eseguire utilizzando ESEGUIRE IMMEDIATO o simili:

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

, ma il successivo sarà OK:

v_sql := 'select * from dual';

Infine, sembra che si desidera restituire i risultati di questa query SQL, non query stessa come una stringa. Sostituire la sua dichiarazione open DENEME for ... con il seguente dovrebbe fare quello che vuoi:

open DENEME for v_sql;

Modifica 2 : Nella procedura, c'è una chiamata commentato-out a DBMS_OUTPUT.PUT_LINE. Hai verificato che il codice SQL generato qui è corretta? In particolare, sono sicuro che nessuno dei valori usati per formare v_query_items e v_pivot_items hanno caratteri ' in loro?

E 'possibile che ci sia un problema utilizzando PIVOT con SQL dinamico. Non lo so, e non posso fare molto di più perché non ho accesso a Oracle 11 qui. Avete ancora ottenere errori se si semplifica l'SQL per una query molto più piccolo, ma uno che ha ancora PIVOT in esso? In altre parole, trovare una semplice query PIVOT che le opere (ad esempio, è possibile eseguire con successo in SQL Developer o simili), scrivere una procedura come la seguente, e vedere se si ottiene alcun indietro i dati da esso:

CREATE OR REPLACE PROCEDURE dynamic_pivot_test(
  results OUT SYS_REFCURSOR
)
AS
BEGIN
  OPEN results FOR 'SELECT ...'; /* put the PIVOT query here. */
END;
/
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top