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

Interfaces de programmation Oracle Discussion :

[OCILIB] Erreur Oracle 22053 (overflow) sur un OCI_GetInt pour une valeur de -2147483648


Sujet :

Interfaces de programmation Oracle

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2011
    Messages : 54
    Points : 67
    Points
    67
    Par défaut [OCILIB] Erreur Oracle 22053 (overflow) sur un OCI_GetInt pour une valeur de -2147483648
    OCILib: 3.9.3
    Oracle client/serveur: v8.1
    Système: Windows 7 / VS2010
    Bonjour,
    Pour un champ NUMBER dans une DB, je récupère la valeur en appelant OCI_GetInt. Tout se passe bien jusqu'à ce que j'arrive sur un champ qui a la valeur -2147483648 (0x80000000) (je dois cleaner la DB de ce genre de valeur venant manifestement de variable pas initialisée). L'erreur Oracle signifie que cette valeur est trop grande pour tenir dans un int (plus exactement un buffer de 4 octets), si j'ai bien compris.
    Je suis assez surpris car:
    - cette valeur tient dans un int
    - dans une autre appli qui utilise directement OCI, OCIStmtFetch retourne bien OCI_SUCCESS, alors que dans le OCIDefineByPos on passe bien sizeof(int) en taille de buffer et SQLT_INT pour le type de donnée.
    En testant un OCI_GetBigInt, je récupère sans erreur un int64 qui vaut 0xffffffff80000000 (= -2147483648).

    Je n'ai rien vu de louche en debuggant jusqu'à arriver à l'appel de la fonction OCI
    Code number.c (line 82) : Sélectionner tout - Visualiser dans une fenêtre à part
    OCINumberToInt(con->err, data, size, sign, value)
    qui provoque l'erreur Oracle.

    Il n'y a que très peu de documentation sur cette erreur, et de personne ayant rencontré ce genre de problème. Même s'il me suffit de récupérer dans un int64, ça me gène de devoir bidouiller pour faire du ménage justement...

    A votre bon coeur Messieurs Dames! Et joyeuses fêtes

  2. #2
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    salut,

    je regarderai ca dans le week end
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  3. #3
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Salut,

    En fait, OCINumberToInt() fait une conversion vers des types natifs de type short, int et long long.

    La valeur que tu mentionnes est bien egale à INT_MIN et donc devrait être convertie par la fonction Oracle.

    Dans ton cas, OCILIB, lors d'un appel à OCI_GetInt(), appelle OCI_NumberToInt() lui demandant de convertir la valeur du NUMBER oracle en un signed int (qui pour info, est en OCI, le type sb4, qui est un typedef sur signed int)

    Mais en regardant de plus pres les headers de OCI, je suis tombé sur des defines dans oratypes.h sur lesquels je n'avais pas fait gaffe aux valeurs et dont un est la source, je pense, de ton souci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define MAXSB4MINVAL ((sb4)-2147483647)
    Donc OCI ne se réfère pas à INT_MIN dans ton cas mais à MAXSB4MINVAL, en interne, et ce qui explique ton erreur d'overflow....
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  4. #4
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2011
    Messages : 54
    Points : 67
    Points
    67
    Par défaut
    Salut!

    En effet, je viens de jeter un oeil sur ce .h, j'avoue être un peu sur le cul:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #define MINUB1MAXVAL ((ub1)  255) 
    #define MAXUB1MINVAL ((ub1)    0) 
    #define MINSB1MAXVAL ((sb1)  127) 
    #define MAXSB1MINVAL ((sb1) -127) 
     
    #define MINUB2MAXVAL ((ub2) 65535) 
    #define MAXUB2MINVAL ((ub2)     0) 
    #define MINSB2MAXVAL ((sb2) 32767) 
    #define MAXSB2MINVAL ((sb2)-32767) 
     
    #define MINUB4MAXVAL ((ub4) 4294967295) 
    #define MAXUB4MINVAL ((ub4)          0) 
    #define MINSB4MAXVAL ((sb4) 2147483647) 
    #define MAXSB4MINVAL ((sb4)-2147483647)
    En gros, en non signé, on peut bien coder toutes les valeurs possibles, mais en signé, on ne peut pas coder la plus petite valeur!

    Valeur min signé sur 8 bits: -128
    Valeur min signé sur 16 bits: -32768
    Valeur min signé sur 32 bits: -2147483648

    J'espère que pour d'obscures raisons c'est voulu, parce que sinon c'est une belle boulette

    Il reste encore le mystère du "Pourquoi ça fonctionne en passant par des OCIDefineByPos puis OCIStmtFetch?". Les 2 seules explications que je vois comme ça serait que ces fonctions soit:
    - n'utilisent pas ces defines pour checker que la valeur peut être stocké dans le buffer donné en param
    - utilisent ces defines, stockent temporairement dans le type de variable qui correspond, puis la tronquent pour la faire passer dans le buffer donné en param

    Dans tous les cas, merci pour l'investigation! Je vais donc rester sur un bigint pour le moment.

Discussions similaires

  1. Réponses: 0
    Dernier message: 05/01/2014, 22h32
  2. [XL-2007] Erreur d'automation - 800401a8 : sur l'activation d'une feuille
    Par sofian.lahlou dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 19/08/2013, 17h44
  3. [PDO] Erreur HY000 lors d'un New PDO pour une connexion sur Mysql
    Par siciliano21 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 22/07/2009, 15h19
  4. [XSLT] Condition sur 1 caractere d'une valeur
    Par syvid dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 08/06/2006, 17h40

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