Précédent   Forum des professionnels en informatique > Bases de données > Oracle > Interfaces de programmation
Interfaces de programmation Forum d'entraide sur l'utilisation des API Oracle : Pré-compilateurs, OCI, OCCI, etc.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/12/2011, 13h44   #1
Invité de passage
 
Homme Vincent Ravier
Développeur informatique
Inscription : décembre 2011
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Vincent Ravier

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

Informations forums :
Inscription : décembre 2011
Messages : 8
Points : 0
Points : 0
Par défaut [OCILIB] Erreur Oracle 22053 (overflow) sur un OCI_GetInt pour une valeur de -2147483648

Citation:
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) :
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
vravier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2011, 22h15   #2
Rédacteur/Modérateur
 
Avatar de Vincent Rogier
 
vincent rogier
Inscription : juillet 2007
Messages : 2 355
Détails du profil
Informations personnelles :
Nom : vincent rogier
Âge : 34

Informations forums :
Inscription : juillet 2007
Messages : 2 355
Points : 3 108
Points : 3 108
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
Vincent Rogier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2012, 00h28   #3
Rédacteur/Modérateur
 
Avatar de Vincent Rogier
 
vincent rogier
Inscription : juillet 2007
Messages : 2 355
Détails du profil
Informations personnelles :
Nom : vincent rogier
Âge : 34

Informations forums :
Inscription : juillet 2007
Messages : 2 355
Points : 3 108
Points : 3 108
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 :
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
Vincent Rogier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2012, 09h00   #4
Invité de passage
 
Homme Vincent Ravier
Développeur informatique
Inscription : décembre 2011
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Vincent Ravier

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

Informations forums :
Inscription : décembre 2011
Messages : 8
Points : 0
Points : 0
Salut!

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

Code :
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.
vravier est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 08h28.


 
 
 
 
Partenaires

Hébergement Web