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

Oracle Discussion :

Fonction SQL DUMP


Sujet :

Oracle

  1. #1
    Membre du Club
    Inscrit en
    Février 2003
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 80
    Points : 47
    Points
    47
    Par défaut Fonction SQL DUMP
    Bonjour à tous,
    Sauriez-vous comment effectuer la conversion inverse de la commande DUMP sous SQL ?
    J'ai des données corrompues invisibles sous sqlplus :
    SELECT monChamp FROM maTable;
    me retourne invariablement "invalid number"

    Grâce à cette commande dump J'ai pu avoir
    SELECT Dump(monChamp) FROM maTable WHERE maTableIndice = 100;
    le résultat Typ=2 Len=4: 64,97,101,102, j'aimerai désormais avoir la valeur numérique de ce résultat : je ne trouve pas de fonction inverse de dump.

    Merci pour votre aide !


  2. #2
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Pourriez-vous faire un dump hexa : dump(colonne, 16) et un utl_raw.cast_from_number(colonne) ?

  3. #3
    Membre du Club
    Inscrit en
    Février 2003
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 80
    Points : 47
    Points
    47
    Par défaut
    SELECT TRANSAC_SN,TO_CHAR(TRANSAC_BAL_AMOUNT) FROM TB_TRANSACTION
    WHERE TRANSAC_SN IN (14875325, 15078724)
    ORDER BY TRANSAC_SN;
    ,TO_CHAR(TRANSAC_BAL_AMOUNT)
    *
    ERROR at line 3:
    ORA-01722: invalid number


    SELECT TRANSAC_SN,TRANSAC_BAL_AMOUNT,DUMP(TRANSAC_BAL_AMOUNT),DUMP(TRANSAC_BAL_AMOUNT, 16)
    FROM TB_TRANSACTION WHERE TRANSAC_SN IN (14875325, 15078724)
    ORDER BY TRANSAC_SN;
    TRANSAC_SN TRANSAC_BAL_AMOUNT DUMP(TRANSAC_BAL_AMOUNT)
    ---------- -------------------------------- ------------------------------------------------------------------
    DUMP(TRANSAC_BAL_AMOUNT,16)
    --------------------------------------------------------------------------------
    14875325 Typ=2 Len=4: 64,97,101,102
    Typ=2 Len=4: 40,61,65,66

    15078724 Typ=2 Len=3: 191,9,1
    Typ=2 Len=3: bf,9,1


    J'ai des petits soucis pour la dernière probablement un problème de droits. Mon but serait de récupérer les données pour les remettre convenablement dans le bon type dans la colonne, j'aimerai éviter de mettre 0 de base.
    Merci encore.

  4. #4
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Je pense que vos données sont déjà corrompues
    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
    26
    27
    28
    29
    30
    31
     
    Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 
    Connected as mni@parvatI
     
    SQL> create table t_num (a number)
      2  /
    Table created
     
    SQL> insert into t_num values (14875325)
      2  /
    1 row inserted
     
    SQL> insert into t_num values (15078724)
      2  /
    1 row inserted
     
    SQL> commit;
    Commit complete
     
    SQL> 
    SQL> Select a,
      2         dump(a,16),
      3         utl_raw.cast_from_number(a)
      4    from t_num
      5  /
             A DUMP(A,16)                                                                       UTL_RAW.CAST_FROM_NUMBER(A)
    ---------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
      14875325 Typ=2 Len=5: c4,f,58,36,1a                                                       C40F58361A
      15078724 Typ=2 Len=5: c4,10,8,58,19                                                       C410085819
     
    SQL>

  5. #5
    Membre du Club
    Inscrit en
    Février 2003
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 80
    Points : 47
    Points
    47
    Par défaut
    Et pour la petite dernière :

    SELECT TRANSAC_SN, utl_raw.cast_from_number(TRANSAC_BAL_AMOUNT) from tb_transaction
    WHERE transac_sn in (15078724 );
    TRANSAC_SN UTL_RAW.CAST_FROM_NUMBER(TRANSAC_BAL_AMOUNT)
    ---------- --------------------------------------------------------------------------------
    15078724 BF0901

    La colonne est un FLOAT. Donc pas moyen de récupérer les données ?

    En tout cas, cette commande DUMP me semble bien utile, y a t'il un moyen pour avoir le résultat en format plus humain. J'ai testé avec des données saines, mais j'ai bien du mal à retrouver la valeur numérique à partir de cette extraction de données.
    dump(100) donne 194, 2
    dump(101) donne 194, 2, 2
    dump(500) donne 194, 6

  6. #6
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    http://docs.oracle.com/cd/B10501_01/...4/oci03typ.htm

    Regarde la partie NUMBER qui explique comment sont stockés en interne les nombres.
    Je n'ai pas essayé de comprendre et de voir pour faire une fonction inverse, mais tu peux t'amuser.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  7. #7
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    L'idée est de reconstituer la valeur à partir des octets affiché par dump via ult_raw
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Select a,
           dump(a,16),
           utl_raw.cast_to_number('C410085819')
      from t_num

  8. #8
    Membre du Club
    Inscrit en
    Février 2003
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 80
    Points : 47
    Points
    47
    Par défaut
    J'ai fait le convertisseur dans l'autre sens ! hélas pour moi, les données sont vraiment corrompues.
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    create or replace FUNCTION reverse_dump (v_dump varchar2)
       RETURN FLOAT 
    AS
       f_res   FLOAT   := 0.0;
     
       n_deb number(10);
       n_fin number(10);
       n_nbr number(10);
       n_expo number(10);
       n_menta number(10);
       /*n_ind number(10);*/
       n number(10) := 0;
     
    BEGIN
    /* Recuperation du nombre d elements */
       n_deb := (instr(v_dump, 'Len') + 4);
       n_fin := (instr(v_dump, ':'));
       n_nbr := TO_NUMBER(substr(v_dump, n_deb, n_fin-n_deb));
     
     
    /* Recuperation de l exposant */
       n_deb := n_fin+2;
       n_fin := (instr(v_dump, ','));
       n_expo := TO_NUMBER(substr(v_dump, n_deb, n_fin-n_deb));
     
    /* 3 cas a gerer : Zero + Positif + Negatif */  
       if n_expo = 128 then 
       /* Zero */
         f_res := 0;
       elsif n_expo > 192 then
       /* Positif */
     
     
         /* Pour chaque menta on calcul sa valeur : on se base sur l'exposant - 193 au facteur 100 multiplué par le menta - 1 */
         for n_ind in 1..n_nbr-1
         loop
           n := n + 1;
           n_deb := n_fin+1;
           n_fin := (instr(v_dump, ',', n_deb));
           if n_deb > n_fin then  
             n_menta := TO_NUMBER(substr(v_dump, n_deb)); 
           else
             n_menta := TO_NUMBER(substr(v_dump, n_deb, n_fin-n_deb));
           end if;  
           f_res := f_res + (100**(n_expo - (192+n)) * (n_menta - 1));
     
         end loop;
        elsif n_expo < 63 then 
       /* Negatif */
         for n_ind in 1..n_nbr-1
         loop
           n := n + 1;
           n_deb := n_fin+1;
           n_fin := (instr(v_dump, ',', n_deb));
           if n_deb > n_fin then  
             n_menta := TO_NUMBER(substr(v_dump, n_deb)); 
           else
             n_menta := TO_NUMBER(substr(v_dump, n_deb, n_fin-n_deb));
           end if;  
           if n_menta = 102 then n_menta := 101; end if;
           f_res := f_res + (100**((63-n) - n_expo) * (n_menta - 101));
         end loop;
     
      end if;   
      RETURN f_res;
    END reverse_dump;

  9. #9
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Une fois que vous avez chopé les octets en Hexa via Dump(*16), la fonction utl_raw.cast_to_number fait le boulot et cela d'une manière fiable et stable sur toutes les versions.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonctions SQL - Tableau et type anyarray
    Par etiennegaloup dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 07/11/2005, 12h25
  2. Syntaxe de la fonction SQL month() ??
    Par merlubreizh dans le forum Langage SQL
    Réponses: 3
    Dernier message: 01/09/2005, 11h16
  3. [Fonction SQL Serveur] convertir des secondes en heure
    Par falcon dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 17/11/2004, 17h22
  4. fonction sql "LIMIT" en interbase?
    Par GMI dans le forum InterBase
    Réponses: 6
    Dernier message: 20/09/2004, 14h04

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