2017-07-25 2 views
0

J'ai une instruction SQL avec l'opération PIVOT. Le nombre maximum de colonnes que j'aurai dans PIVOT est de 5, mais je peux en avoir moins, 4, 3, 2. Comment puis-je lire ces colonnes dans mon curseur et affecter (chercher ... dans ...) aux variables fixes , sans survenir l'erreur ORA-01007.Comment extraire les valeurs de curseur du code SQL du pivot vers les variables fixes - Erreur ORA-01007

... 
sql_stmt := 'select * from 
       (select codcoligada, 
         idprd, 
         codcfo, 
         valnegociado 
       from tcitmorcamento 
       where codcoligada = ' || p_codcoligada || ' 
        and codcotacao = ' || '''' || p_codcotacao || '''' || ') 
       pivot 
       (
        sum(valnegociado) for codcfo in (' || pivot_clause || ') 
       )'; 

    ret := t_tab_sesa_cotacao(); 

    open vCursor for sql_stmt; 

    loop 
    /* If my cursor returns less than 5 columns in PIVOT the error occurs ORA-01007 */ 
    fetch vCursor into vCodColigada, vIdProduto, vValor01, vValor02, vValor03, vValor04, vValor05; 
    exit when vCursor%NOTFOUND; 
     ret.extend; 
     ret(ret.count) := t_type_sesa_cotacao(vCodColigada, vIdProduto, vValor01, vValor02, vValor03, vValor04, vValor05); 
    end loop; 

    close vCursor; 
... 

Si je reviens à moins de 5 colums, je veux remplir le reste des variables avec une valeur de 0 ou null.

Les variables vCodColigada et vIdProduto sont identifiés, seuls les colonnes pivots qui peuvent varier entre 1 et 5 (vValor1, vValor2, vValor3, vValor4, vValor5)

Résultat PIVOT SQL:

CODCOLIGADA  IDPRD   '000125'   '002272'   '002342'   
----------------- ---------------- ---------------- ---------------- ---------------- 
       1   15464    45    300    30 
       1   18460    35    200    20 
       1   57492    20    100    10 
-------- End of Data -------- 

Exemple: Si le curseur renvoie 3 valeurs dans le PIVOT (ci-dessus), les variables vValor01, vValor02, vValor03 seront remplies, et les variables vValor04, vValor05 doivent être 0 ou nulles.

Exemple:

CODCOLIGADA  IDPRD   VALOR01   VALOR02   VALOR03   VALOR04   VALOR05   
----------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- 
       1   15464    45    300    30    0    0 
       1   18460    35    200    20    0    0 
       1   57492    20    100    10    0    0 
-------- End of Data -------- 

Comme je l'ai seulement 3 colonnes en PIVOT, et je 5 variables, l'erreur ORA-01007 se produit dans (extraction .. en ...).

Répondre

1

Espérons que cet extrait ci-dessous aide. Ce que la compréhension de base est que nous devons ajouter la variable excédentaire comme nulle ou vide pour faire ce travail.

SET serveroutput ON; 
DECLARE 
    lv_pivot VARCHAR2(100):='''Y'',''N'''; 
TYPE lv 
IS 
    RECORD 
    (
    flg_y VARCHAR2(100), 
    flg_n VARCHAR2(100), 
    flg_e VARCHAR2(100)); 
type lv_tab 
IS 
    TABLE OF lv; 
    lv_num lv_tab; 
    lv_check VARCHAR2(1000); 
BEGIN 
    lv_check :=regexp_count(lv_pivot,',',1); 
    IF lv_check < 3 THEN 
    FOR z IN 1..(2-lv_check) 
    LOOP 
     lv_pivot:=lv_pivot||',null as val'||z; 
    END LOOP; 
    ELSE 
    lv_pivot:=lv_pivot; 
    END IF; 
    dbms_output.put_line(lv_pivot); 
    EXECUTE IMMEDIATE ' SELECT * FROM       
(SELECT col1 FROM <table> )      
pivot (COUNT(1) FOR col1 IN ('||lv_pivot||'))' BULK COLLECT INTO lv_num; 
END; 


---------------------------Refactoring in Function------------------------------ 

--Create Object Type 
CREATE OR REPLACE TYPE lv_obj IS OBJECT 
(
     flg_y VARCHAR2(100), 
     flg_n VARCHAR2(100), 
     flg_e VARCHAR2(100) 
); 

--Create Table Type 
CREATE OR REPLACE TYPE lv_tab IS TABLE OF lv_obj; 

--Create Function 
CREATE OR REPLACE 
    FUNCTION test_func 
    RETURN lv_tab 
    AS 
    lv_pivot VARCHAR2(100):='''Y'',''N'''; 
    lv_num lv_tab; 
    lv_check VARCHAR2(1000); 
    BEGIN 
    lv_check :=regexp_count(lv_pivot,',',1); 
    IF lv_check < 3 THEN 
     FOR z IN 1..(2-lv_check) 
     LOOP 
     lv_pivot:=lv_pivot||',null as val'||z; 
     END LOOP; 
    ELSE 
     lv_pivot:=lv_pivot; 
    END IF; 
    dbms_output.put_line(lv_pivot); 
    EXECUTE IMMEDIATE ' SELECT * FROM       
(SELECT col1 FROM <table> )      
pivot (COUNT(1) FOR col1 IN ('||lv_pivot||'))' BULK COLLECT INTO lv_num; 
    RETURN lv_tab; 
    END; 

-------------------------------------------------Output----------------------------------------------- 

SELECT * FROM TABLE(test_func); 
------------------------------------------------------------------------------------------------------- 
+0

Merci, la solution a fonctionné. Comment pourrais-je retourner ce type (lv_num) par une fonction? –

+0

J'ai refactorisé la sortie dans Function. J'espère que cela aide. –

+0

Merci pour votre aide. Cette erreur se produit: ORA-00932: types de données incohérents: expected - got - –

-1

Essayez de remplir les résultats dans la requête. Ajoutez une jointure à une sélection de double instruction qui renvoie les cinq colonnes.

+0

S'il vous plaît. Pouvez-vous donner un exemple? –