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] - Valeur de colonne à NULL erronée avec l'utilisation du PreFetch


Sujet :

Interfaces de programmation Oracle

  1. #1
    Membre actif
    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
    Par défaut [OCILIB] - Valeur de colonne à NULL erronée avec l'utilisation du PreFetch
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    OCILib: 3.9.3
    Oracle client/serveur: v8.1
    Système: Windows 7 / VS2010
    Bonjour,

    Je me suis aperçu d'un petit problème lorsque j'utilise OCI_SetPrefetchSize avec une valeur supérieure à 1.
    Dans mon cas, le bug apparait lorsque je fais une requête en récupérant juste 2 colonnes sur les 6 d'une table contenant environ 250 enregistrements.
    La colonne 1 est un nombre, et la colonne 2 est un varchar2 qui peut être NULL.
    Et voici le petit bout de code que j'utilise pour tester:
    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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    int TestOCILib()
    {
    	if(OCI_Initialize(err_handler, "C:\\oracle\\ora81\\bin", OCI_ENV_DEFAULT) == false)
    	{
    		return -1;
    	}
     
    	printf("OCILib initialized\n");
     
    	OCI_Connection* pConnection = OCI_ConnectionCreate(DATABASENAME, USER, PWD, OCI_SESSION_DEFAULT);
    	if(pConnection == nullptr)
    	{
    		return -1;
    	}
     
    	FILE* pFile = fopen(FILENAME, "wt");
    	if(pFile == nullptr)
    	{
    		return -1;
    	}
     
    	printf("Connected to database\n");
     
    	OCI_Statement* pStatement = OCI_StatementCreate(pConnection);
    	const bool bSetPrefetchResult = OCI_SetPrefetchSize(pStatement, PREFETCHSIZE);
    	if(bSetPrefetchResult == false)
    	{
    		return -1;
    	}
     
    	OCI_ExecuteStmt(pStatement, REQUEST);
    	printf("Request in progress...\n");
     
    	OCI_Resultset* pResultSet = OCI_GetResultset(pStatement);
     
    	bool bFetchOk = true;
    	while(bFetchOk == true)
    	{
    		bFetchOk = OCI_FetchNext(pResultSet) != 0;
     
    		if(bFetchOk == true)
    		{
    			unsigned int const uiColNb = OCI_GetColumnCount(pResultSet);
     
    			for(unsigned int uiColIndex = 1; uiColIndex <= uiColNb; uiColIndex++)
    			{
    				OCI_Column* pColumn = OCI_GetColumn(pResultSet, uiColIndex);
    				char szColName[100];
    				strcpy(szColName, OCI_GetColumnName(pColumn));
    				const char* szType = OCI_GetColumnSQLType(pColumn);
     
    				fprintf(pFile, "%s = ", szColName);
     
    				// varchar2
    				if(strcmp(szType, "VARCHAR2") == 0)
    				{
    					const char* szColValue = OCI_GetString(pResultSet, uiColIndex);
    					fprintf(pFile, "%s", szColValue == nullptr ? "NULL" : szColValue);
    				}
    				// float
    				else if(strcmp(szType, "FLOAT") == 0)
    				{
    					const float fValue = (float)OCI_GetDouble(pResultSet, uiColIndex);
    					fprintf(pFile, "%f", fValue);
    				}
    				// integer/number
    				else if(	strcmp(szType, "INTEGER") == 0
    					||	strcmp(szType, "NUMBER") == 0)
    				{
    					const int iValue = (int)OCI_GetBigInt(pResultSet, uiColIndex);
    					fprintf(pFile, "%d", iValue);
    				}
     
    				fprintf(pFile, "\n");
    			}
     
    			fprintf(pFile, "\n");
    		}
    	}
     
    	OCI_ReleaseResultsets(pStatement);
    	OCI_FreeStatement(pStatement);
    	OCI_FreeConnection(pConnection);
     
    	fclose(pFile);
     
    	printf("\n\nDone!");
     
    	return 0;
    }
    Ca me sort un fichier du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    COLONNE1 = 1
    COLONNE2 = un peu de texte
     
    COLONNE1 = 2
    COLONNE2 = NULL
     
    etc...
    Et avec un prefetch > 1, arrivé à certains enregistrements pour lesquels la colonne VARCHAR2 est à NULL, la valeur retournée pour cette colonne est celle d'une quinzaine d'enregistrement avant.
    Autre fait intéressant, si je modifie ma requête, et que j'écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select colonne1, nvl(colonne2, ' ') from ma_table;
    Les colonnes qui sont à NULL me retournent toutes bien une chaine de caractères avec uniquement un espace, quelque soit la taille du prefetch.

    En voulant tester en appelant directement le code OCI, il est de toute façon nécessaire de spécifier un nvl pour les colonnes qui peuvent être NULL.
    Donc le problème, s'il existe dans cette couche de code, n'apparait pas.

    Si c'est pas bien clair (et ça ne l'est probablement pas ), j'ajouterai des précisions.

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

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

    Peut tu me fournir par mail un jeu de test (source c simple complet, DDL de create de la table et DML d'insertion de données) ?

    As tu le soucis sous d'autres version d'Oracle ?

    Je vais investiguer....
    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
    Membre actif
    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
    Par défaut
    Salut,

    Je ne peux malheureusement pas tester avec d'autres versions d'Oracle (client et/ou serveur), nous n'avons que celle-ci qui tourne.

    Les données étant sensibles, je vais essayer de faire un jeu de test qui reproduit le problème. Je poste tout ça le plus vite possible.

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Par défaut
    ok

    Envoi ca par mail à l'adresse du support d'OCILIB (support@ocilib.net) !
    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

  5. #5
    Membre actif
    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
    Par défaut
    C'est envoyé!

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Par défaut
    Recu

    Je vais investiguer et voir si cela provient de OCILIB ou de OCI (je sais qu'il y a eu des soucis avec le prefetch mentionné sur metalink).

    Malheureusement, je suis en congé de demain à dimanche. Je pourrait te donner des nouvelle seulement lundi prochain....

    Je vais essayer de m'y coller un peu ce soir mais c'est pas garanti....
    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

  7. #7
    Membre actif
    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
    Par défaut
    Oulala, pas d'urgence Surtout qu'un workaround très simple consiste à coller des nvl dans les requêtes avec une chaine de caractères bien spécifique genre "__NULL__", un petit strcmp, et le tour est joué.

    En tout cas, merci d'y consacrer un peu de temps.

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

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

    Je ne peux reproduire le problème.
    En consultant metalink (oracle support), ce que tu decris a déja été identifié :

    Bug 1315603:

    OCI RETURNS INCORRECT INDP & RCODEP VALUES WHEN FETCHING NULL DATA).

    DESC :
    On an 8.1.6.1.1 client, if OCI_ATTR_PREFETCH_ROWS is set, OCI returns
    incorrect indicator & return code values when fetching NULL data.

    C'est don un bug Oracle et cela ne concerne que les version d'oracle <=8.1.6.
    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

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 02/06/2015, 02h28
  2. [AC-2007] Champs père-fils avec valeur vide ou null
    Par Piou2fois dans le forum IHM
    Réponses: 5
    Dernier message: 08/11/2013, 11h43
  3. Remplacer valeurs dans colonne avec R
    Par pjulie dans le forum R
    Réponses: 2
    Dernier message: 28/08/2013, 23h55
  4. [2008R2] Ajout de colonne et insertion avec les valeur d'une autre colonne (ligne+1)
    Par diidouu dans le forum Développement
    Réponses: 3
    Dernier message: 30/04/2013, 15h15
  5. [XL-2007] copier coller valeur dans une autre feuille avec itération de colonne
    Par profnans dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 24/02/2013, 19h21

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