Question

A qui il peut répondre, Nous aimerions utiliser la fonction SELECT avec l'option PIVOT à un SGBD Oracle 11g R2. Notre requête est comme:

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

Comme on le voit, XML est commentée, si l'exécution en XML PIVOT donne la sortie correcte au format XML, mais nous sommes tenus d'obtenir les données sous forme de données de pivot sans mise en forme, mais cette phrase jette l'erreur: ORA-00936: expression manquant

Toutes les résolutions ou les idées seraient les bienvenues,

Cordialement

------------- sale mais proc de travail est inférieure à ------------------------

mise à jour par la procédure 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;
Était-ce utile?

La solution 2

la procédure modifiée à 17.01.2011 est sale mais travail, les curseurs en boucle devrait changer, mieux err. la manipulation de la sql dynamique (actuellement sans pareil), va essayer de l'améliorer quand eu le temps. Merci à tous pour votre aide.

Autres conseils

Je n'ai pas une instance Oracle 11 est disponible pour moi maintenant (PIVOT est nouveau dans Oracle 11), donc je ne peux que spéculer. Je suppose que le -- a fini de commenter tout ce qui suit le pivot, et Oracle vous a donné une erreur « manque d'expression » parce qu'il attendait de trouver quelque chose après pivot. Avez-vous essayé commentant xml en l'entourant avec /* et */ au lieu de mettre -- avant qu'il ne?

Si vous utilisez cette requête de Java, par exemple, alors je vous attendre à obtenir une erreur « expression manquante » si vous avez tenté d'exécuter le SQL dans la chaîne suivante:

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

Parce que cette chaîne SQL se concaténée en une seule ligne, la -- devant xml provoquera Oracle d'ignorer tout dans la requête après.

EDIT : Dans la procédure que vous avez ajouté, ce qui me préoccupe est cette partie (en abrégé):

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

open DENEME for
select v_sql from dual;

Je ne comprends pas pourquoi vous utilisez BEGIN et END au sein v_sql. Essayez de les supprimer.

En outre, prendre soin de ne pas laisser un point-virgule final dans votre chaîne d'instruction SQL. Ce qui suit donnera une erreur de ORA-00911: invalid character si vous essayez de l'exécuter en utilisant EXECUTE IMMEDIATE ou suchlike:

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

mais ce qui suit sera OK:

v_sql := 'select * from dual';

Enfin, il semble que vous voulez retourner les résultats de cette requête SQL, pas la requête elle-même comme une chaîne. Le remplacement de votre déclaration de open DENEME for ... avec ce qui suit devrait faire ce que vous voulez:

open DENEME for v_sql;

EDIT 2 : Dans votre procédure, il y a un appel en commentaire à DBMS_OUTPUT.PUT_LINE. Avez-vous vérifié que le SQL généré ici est correcte? En particulier, vous êtes sûr qu'aucune des valeurs utilisées pour former v_query_items et v_pivot_items ont des caractères ' en eux?

Il est peut-être qu'il ya un problème à l'aide PIVOT avec SQL dynamique. Je ne sais pas, et ne peut pas aider beaucoup plus parce que je n'ai pas accès à Oracle 11 ici. Avez-vous encore des erreurs si vous simplifiez le SQL à une requête beaucoup plus petite, mais qui a encore PIVOT en elle? En d'autres termes, trouver une simple requête PIVOT que les travaux (par exemple, vous pouvez l'exécuter avec succès dans Developer ou suchlike SQL), écrire une procédure comme la suivante, et voyez si vous obtenez tout retour de données de celui-ci:

CREATE OR REPLACE PROCEDURE dynamic_pivot_test(
  results OUT SYS_REFCURSOR
)
AS
BEGIN
  OPEN results FOR 'SELECT ...'; /* put the PIVOT query here. */
END;
/
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top