IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

Nom de colonnes non statiques


Sujet :

SQL Oracle

  1. #1
    Membre confirmé
    Inscrit en
    Août 2006
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 123
    Par défaut Nom de colonnes non statiques
    bonjour,
    je cherche pour des besoins spécifiques, à retourner une table avec des noms de colonnes qui se varient selon la date du système:
    exemple du résultat attendu :
    SOMME042011
    --------------
    20
    30
    j'ai essayé avec la requête suivante mais ça se compile pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select s.total as (select 'SOMME/'||to_char(sysdate,'MONYYYYMM') from dual) from sommes s where ...
    comment faire pour avoir le bon résultat ? est ce que je dois passer par une procédure stocké ?

    Merci

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Oui, avec du SQL dynamique.
    Mais à mon avis vous devriez procéder à ce changement "ailleurs".

    Que faites-vous de ces données ?

  3. #3
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 462
    Par défaut
    Si c'est dans SQL*Plus, ça peut se faire grâce à la variable de substitution prédéfinie _DATE.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SQL> alter session set nls_date_format='DDMMYYYY';
     
    SQL> select count(*) AS col&_DATE from user_objects;
     
    COL14042011
    -----------
          23121

  4. #4
    Membre confirmé
    Inscrit en
    Août 2006
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 123
    Par défaut
    Bonjour, et merci pour les réponses.
    Que faites-vous de ces données ?
    je développe une procédure stocké, et parmi les éléments retournés, il y a une colonne qui doit avoir comme nom COL/MONYYYYMM (exemple AVR201104).

    Si c'est dans SQL*Plus, ça peut se faire grâce à la variable de substitution prédéfinie _DATE.
    Je travaille avec l'outil Toad,lorsque j'essaie setter la date session avec le format "MONYYYYMM", une erreur se produit :
    ORA-01816: le mois ne peut être indiqué qu'une seule fois

  5. #5
    Membre Expert Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Par défaut
    Citation Envoyé par edogawa Voir le message
    Je travaille avec l'outil Toad,lorsque j'essaie setter la date session avec le format "MONYYYYMM", une erreur se produit :
    Le formattage de la date pour NLS exige que chaque champs ne soit représenté qu'une fois (l'année, le mois, les secondes ...)

    Lorsque vous donnez le format MONYYYYMM, MON et MM représentent tous les deux le mois, pour utiliser la méthode décrite par Pomalaix il faut choisir une et une seule représentation du mois.

    Vous pouvez utiliser une variable que vous définissez vous même :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    14:16:34 SQL> column madate new_value ladate noprint
    14:16:41 SQL> select to_char(sysdate,'MONYYYYMM') madate from dual;
     
    1 row selected.
     
    14:16:45 SQL> select sysdate "col&ladate" from dual;
    old   1: select sysdate "col&ladate" from dual
    new   1: select sysdate "colAVR. 201104" from dual
     
    colAVR. 201104
    -------------------
    15/04/2011,14:16:51
     
    1 row selected.

  6. #6
    Membre confirmé
    Inscrit en
    Août 2006
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 123
    Par défaut
    Bonjour,
    Merci encore pour les réponses,
    Avec la procédure que je développe, il y a plusieurs colonnes que je dois retourner avec un nom dépendant de la date: je m'explique :
    SOMME042011 | SOMME032011 | SOMME022011
    ---------------------------------------------
    10 10 10
    20 30 40
    qu'est ce que vous pouvez me proposez pour ce cas ?

    Merci beaucoup de votre aide et excusez moi pour ces questions, je suis pas un expert PL SQL..

  7. #7
    Membre Expert Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Par défaut
    Disons que la description du problème est un peu courte ... Alors on va imaginer

    J'imagine donc que vous avez une table à 3 colonnes, l'une contant des dates, une autre des valeurs numérique et la troisième des valeurs de regroupement. Bref la table de gestion des dépenses par postes (par exemple)

    Bref j'imagine une jolie table comme celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    LA_DATE     POSTE_DEP        DEPENSES
    ----------- ---------------- --------
    01/01/2011  Bouffe                112
    02/01/2011  Voiture                70
    10/01/2011  Bouffe                250
    15/01/2011  Voiture                67
    17/01/2011  Loisirs                30
    25/01/2011  Bouffe                310
    27/01/2011  Voiture                68
    31/01/2011  Loisirs                42
    01/02/2011  Bouffe                132
    02/02/2011  Voiture                30
    10/02/2011  Bouffe                230
    15/02/2011  Voiture                37
    17/02/2011  Loisirs                30
    25/02/2011  Bouffe                340
    27/02/2011  Voiture                48
    01/03/2011  Bouffe                143
    02/03/2011  Voiture                43
    10/03/2011  Bouffe                243
    15/03/2011  Voiture                43
    17/03/2011  Loisirs                33
    25/03/2011  Bouffe                313
    27/03/2011  Voiture                63
    31/03/2011  Loisirs                43
    Donc nous voilà en avril 2011 et j'imaine que vous voulez faire un bilan financier du premier trimestre ...

    Solution n°1 je me paluche la requête :

    Version avant la 11g :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select POSTE
         , sum ( decode ( to_char(LA_DATE,'YYYYMM') ,'201101',DEPENSE,0 ) ) SOMME201101
         , sum ( decode ( to_char(LA_DATE,'YYYYMM') ,'201102',DEPENSE,0 ) ) SOMME201102
         , sum ( decode ( to_char(LA_DATE,'YYYYMM') ,'201103',DEPENSE,0 ) ) SOMME201103
    from dep_ext
    group by POSTE ;
    Version 11g

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT * 
    FROM ( SELECT 'SOMME'||to_char(LA_DATE,'YYYYMM') LE_MOIS 
                , poste
                , depense  
    	   FROM dep_ext) PIVOT ( SUM(DEPENSE) FOR LE_MOIS IN ('SOMME201101','SOMME201102','SOMME201103') );
    Simple, efficace, mais il faut se la retaper tous les mois ...

    Solution n°2 j'écris un code PL/SQL qui me génère cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SQL> create or replace function gen_req return clob is
      2   ret   clob;
      3   ttext varchar2(32767);
      4  begin
      5   ret := 'select POSTE'||chr(10);
      6   ttext:='';
      7   for c in ( select distinct to_char(LA_DATE,'YYYYMM') fil from dep_ext )
      8   loop
      9    ttext:=ttext||'     , sum ( decode ( to_char(LA_DATE,''YYYYMM'') ,'''||trim(c.fil)||''',DEPENSE,0 ) ) SOMME'||trim(c.fil)||chr(10);
     10   end loop;
     11   ttext:=ttext||'from dep_ext'||chr(10)||'group by POSTE ;'||chr(10);
     12   dbms_lob.writeappend(ret,length(ttext),ttext);
     13   return ret ;
     14  end gen_req ;
     15  /

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SQL> select gen_req from dual;
     
    GEN_REQ
    -------------------------------------------------------------------------------------------------
    select POSTE
         , sum ( decode ( to_char(LA_DATE,'YYYYMM') ,'201101',DEPENSE,0 ) ) SOMME201101
         , sum ( decode ( to_char(LA_DATE,'YYYYMM') ,'201102',DEPENSE,0 ) ) SOMME201102
         , sum ( decode ( to_char(LA_DATE,'YYYYMM') ,'201103',DEPENSE,0 ) ) SOMME201103
    from dep_ext
    group by POSTE ;
     
     
    1 ligne sÚlectionnÚe.
    Le résultat de la requête une fois exécutée est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    POSTE                                              SOMME201101 SOMME201102 SOMME201103
    -------------------------------------------------- ----------- ----------- -----------
    Bouffe                                                     672         702         699
    Voiture                                                    205         115         149
    Loisirs                                                     72          30          76
    Mais bon comme j'ai imaginé pas mal de trucs, je ne suis pas certains du tout que ce soit exactment ce que vous attendez

  8. #8
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 955
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 955
    Par défaut
    Effectivement il faut faire du sql dynamique pour pivoter les lignes, mais autant renvoyer un curseur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CREATE OR REPLACE procedure gen_req2(ret out sys_refcursor) IS
         ttext varchar2(32767);    
        begin
         ttext := 'select POSTE_DEP ';
         FOR c IN ( SELECT DISTINCT to_char(LA_DATE,'YYYYMM') fil FROM dep_ext )
         loop
          ttext:=ttext||'     , sum ( decode ( to_char(LA_DATE,''YYYYMM'') ,'''||trim(c.fil)||''',DEPENSES,0 ) ) SOMME'||trim(c.fil);
        end loop;
        ttext:=ttext||' from dep_ext group by POSTE_DEP';
        --dbms_output.put_line(ttext);
        open ret for ttext;
       end;
       /
    Et pour l'exécuter dans sqlplus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SQL> var rc refcursor
    SQL> execute gen_req2 (:rc)
     
    PL/SQL procedure successfully completed.
     
    SQL> print rc
     
    POSTE_D SOMME201101 SOMME201102 SOMME201103
    ------- ----------- ----------- -----------
    Bouffe          672         702         699
    Voiture         205         115         149
    Loisirs          72          30          76
    PRINT c'est la méthode sqlplus pour fetch le curseur, à transposer au langage client utilisé.

    Sinon il y a aussi la méthode PIVOT de tom kyte.

Discussions similaires

  1. Réponses: 1
    Dernier message: 21/01/2011, 16h17
  2. Réponses: 5
    Dernier message: 02/12/2010, 17h04
  3. Trigger INSERT : nom de colonne non valide
    Par arthuro45 dans le forum Développement
    Réponses: 6
    Dernier message: 13/09/2010, 22h58
  4. [requete] Nom de colonne non reconnue
    Par OverOne dans le forum Langage SQL
    Réponses: 4
    Dernier message: 25/06/2008, 18h43
  5. [SSIS] [2K5] : Nom de colonne non valide
    Par Adorien dans le forum SSIS
    Réponses: 0
    Dernier message: 13/05/2008, 17h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo