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] OCI_BindString sur une chaine contenant un caractère NULL (chr(0))


Sujet :

Interfaces de programmation Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2009
    Messages : 41
    Par défaut [OCILIB] OCI_BindString sur une chaine contenant un caractère NULL (chr(0))
    Bonjour,

    Voici une nouvelle problématique

    Pour un besoin bien particulier, j'ai besoin de générer le genre de requête suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT /*+ index(MATABLE IDX1_MATABLE) */ ROWID, COL_CHAR1, COL_CHAR2,COL_NUMBER1 FROM MATABLE 
    WHERE 
    (COL_CHAR1 || COL_CHAR2 || TO_CHAR(COL_NUMBER1,'9')) 
    >= 
    (:COL_CHAR1 || :COL_CHAR2 || TO_CHAR(:COL_NUMBER1,'9'))
    Le Bind de la première colonne est effectué avec un OCI_BindString
    Le Bind de la deuxième colonne est effectué avec un OCI_BindString
    Le Bind de la troisième colonne est effectué avec un OCI_BindInt

    Le premier bind contient par exemple AAAA mais j'ai besoin d'affecté dans la deuxième colonne une valeur de type chr(0) (plus petit caractère dans la table ascii) et dans la troisième la valeur 0.

    Pouvez-vous me confirmer le comportement d'OCI_BindString pour la deuxième colonne dans ce cas (est-ce que le caractère de valeur nul est bindé dans ce cas)?
    J'ai le sentiment que OCI_BindString malgré la taille de la chaine passée à 1 'traite la chaine comme un null'


    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    create table matable (col_char1 char(4), col_char2 char(1), col_number1(1));
    create index idx1 on matable(COL_CHAR1 || COL_CHAR2 || TO_CHAR(COL_NUMBER1,'9'));
     
    insert into matable (col_char1,col_char2,col_number1) values ('AAAA',null,0);
    insert into matable (col_char1,col_char2,col_number1) values ('AAAA',' ',0);
    insert into matable (col_char1,col_char2,col_number1) values ('AAAA','A',0);
    insert into matable (col_char1,col_char2,col_number1) values ('AAAA','B',0);

    Pour information, la requête suivante renvoie bien ce que je veux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT /*+ index(MATABLE IDX1_MATABLE) */ ROWID, COL_CHAR1, COL_CHAR2,COL_NUMBER1 FROM MATABLE 
    WHERE 
    (COL_CHAR1 || COL_CHAR2 || TO_CHAR(COL_NUMBER1,'9')) 
    >= 
    ('AAAA' || ' ' || TO_CHAR(0,'9'))
    Pour information, la requête suivante renvoie bien ce que je veux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT /*+ index(MATABLE IDX1_MATABLE) */ ROWID, COL_CHAR1, COL_CHAR2,COL_NUMBER1 FROM MATABLE 
    WHERE 
    (COL_CHAR1 || COL_CHAR2 || TO_CHAR(COL_NUMBER1,'9')) 
    >= 
    ('AAAA' || chr(0) || TO_CHAR(0,'9'))
    Pour information, la requête suivante ne renvoie pas ce que je veux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT /*+ index(MATABLE IDX1_MATABLE) */ ROWID, COL_CHAR1, COL_CHAR2,COL_NUMBER1 FROM MATABLE 
    WHERE 
    (COL_CHAR1 || COL_CHAR2 || TO_CHAR(COL_NUMBER1,'9')) 
    >= 
    ('AAAA' || null || TO_CHAR(0,'9'))
    Pour info:
    SQL> select * from v$version;

    BANNER
    --------------------------------------------------------------------------------
    Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
    PL/SQL Release 11.1.0.6.0 - Production
    CORE 11.1.0.6.0 Production
    TNS for HPUX: Version 11.1.0.6.0 - Production
    NLSRTL Version 11.1.0.6.0 - Production

    Version ocilib 3.4.0

    D'avance merci.
    Fly.
    Fichiers attachés Fichiers attachés

  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
    la requete suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT /*+ index(MATABLE IDX1_MATABLE) */ ROWID, COL_CHAR1, COL_CHAR2,COL_NUMBER1 FROM MATABLE 
    WHERE 
    (COL_CHAR1 || COL_CHAR2 || TO_CHAR(COL_NUMBER1,'9')) 
    >= 
    ('AAAA' || '' || TO_CHAR(0,'9'))
    ne renverra pas non plus le bon résultat.

    Pourquoi ? car <''> et <NULL> sont équivalents sous Oracle

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select dump(chr(0)), dump(''), dump(NULL) from dual;
     
    DUMP(CHR(0))   DUMP('') DUMP(NULL)
    ============== ======== ==========
    Typ=1 Len=1: 0 NULL    NULL
    Ce que tu peux essayer de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT /*+ index(MATABLE IDX1_MATABLE) */ ROWID, COL_CHAR1, COL_CHAR2,COL_NUMBER1 FROM MATABLE 
    WHERE 
    (COL_CHAR1 || COL_CHAR2 || TO_CHAR(COL_NUMBER1,'9')) 
    >= 
    (:COL_CHAR1 || NVL(:COL_CHAR2, CHR(0)) || TO_CHAR(:COL_NUMBER1,'9'))
    Exemple :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT /*+ index(MATABLE IDX1_MATABLE) */ ROWID, COL_CHAR1, COL_CHAR2,COL_NUMBER1 FROM MATABLE 
    WHERE 
    (COL_CHAR1 || COL_CHAR2 || TO_CHAR(COL_NUMBER1,'9')) 
    >= 
    ('AAAA' || nvl('', chr(0)) || TO_CHAR(0,'9'));
     
    ROWID           COL_CHAR1 COL_CHAR2 COL_NUMBER1
    ================== ========= ========= 
    AAAF87AAEAAAEiIAAB AAAA              0
    AAAF87AAEAAAEiIAAA AAAA              0
    AAAF87AAEAAAEiIAAC AAAA      A             0
    AAAF87AAEAAAEiIAAD AAAA      B             0
    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 averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2009
    Messages : 41
    Par défaut
    Merci Vincent,

    Donc pour résumer, un OCI_BindString avec une longueur > 0 et une chaine composée de caractères ASCII de valeur 0 se traduira par un NULL au niveau du bind ?

    Je me doutais que la piste du NVL était nécessaire ....

    Fly.

  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
    Ben en fait, C'est pas ocilib qui dit que c'est NULL (le seul moyen de le spécifier pour chaine de caracteres, c'est OCI_BindSetNull() ou OCI_SetNull()) mais oracle lui meme !

    Si tu n'as pas appelé une de ces deux fonctions, OCILIB passe la valeur de ta string à OCI et dis qu'elle est pas nulle.

    Si Oracle insère un NULL, c'est parce que pour lui <''> == <NULL>

    Je ne peux rien faire contre....
    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

Discussions similaires

  1. Réponses: 1
    Dernier message: 26/05/2010, 17h57
  2. Nettoyer une chaine contenant des caractères spéciaux?
    Par adil_vpb dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 30/05/2007, 15h47
  3. Réponses: 1
    Dernier message: 22/01/2007, 20h33
  4. prèlèvements sur une chaine de caractères
    Par Nicobp dans le forum Langage
    Réponses: 2
    Dernier message: 11/10/2006, 01h14
  5. Dégradé sur une chaine de caractères avec 3 a 4 couleurs
    Par avogadro dans le forum Composants VCL
    Réponses: 6
    Dernier message: 31/03/2006, 13h21

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