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

PL/SQL Oracle Discussion :

Insérer la valeur NULL dans une colonne de type number


Sujet :

PL/SQL Oracle

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut Insérer la valeur NULL dans une colonne de type number
    Bonjour,
    je suis en train de faire une requête dynamique. Afin de récupérer la valeur de mon curseur DBMS_SQL, je crée une table temporaire. J'insère dans cette table les valeurs des colonnes récupérées à partir de mon curseur sous forme de variables.
    Mon problème intervient lorsque l'une des valeurs NUMBER est vide.
    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    vSqlInsert           VARCHAR2(4000);
    vSqlInsert :=  'INSERT INTO ' || pDynamicViewName || ' VALUES (''' ||  
                                variablestring1 || ''', ' ||
                                variablenumber || ', ''' || 
                                variablestring2 || ''')';
    DBMS_OUTPUT.PUT_LINE(vSqlInsert);
    Ceci m'affiche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO DynamicViewName VALUES ('valeurstring1', , 'valeurstring2')
    Et ceci me donne à l'exécution l'erreur suivante :
    ORA-00936: missing expression
    Ce que je veux est qu'au lieu d'avoir un espace vide, j'ai la valeur NULL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO DynamicViewName VALUES ('valeurstring1', NULL, 'valeurstring2')
    ce qui fonctionne.

    J'ai essayé de remplacer number par nvl(number , NULL) mais ça revient au même. Et évidemment si je fais nvl(number , 'NULL'), il y a l'erreur
    ORA-06502: PL/SQL: numeric or value error: character to number conversion error
    J'espère avoir été assez claire, cela fait un moment que je planche la dessus et je n'ai rien trouvé sur internet...
    Merci pour votre aide

  2. #2
    Membre confirmé Avatar de NGasparotto
    Inscrit en
    Janvier 2007
    Messages
    421
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 421
    Points : 603
    Points
    603
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    nvl(to_char(variablenumber),'''''')|| ', ''' ||
    ...
    ou (c'est la meme chose)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    nvl(to_char(variablenumber),'null')|| ', ''' ||
    ...
    Ceci dit, je n'ai jamais vraiment compris le besoin absolu de creer une table a la volee, surtout en considerant le danger qu'une autre session fasse la meme chose, et alors gros probleme...
    Peut-etre est-ce le moment de penser aux vrais "global temporary table" qui elles ont une existence definitive (mais pas leurs donnees) ?

    Nicolas.

  3. #3
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Citation Envoyé par cocoaparis Voir le message
    J'espère avoir été assez claire, cela fait un moment que je planche la dessus et je n'ai rien trouvé sur internet...
    Merci pour votre aide
    Avec la mise en page ça l'est beaucoup plus

    T'as aussi la solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vSqlInsert :=  REPLACE(vSqlInsert , ', ,', ', NULL,');

  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
    Voilà le type de problème à attendre quand on ignore l'utilisation des variables des liaison. Et que est-ce qu'il adviendra si par exemple la variable varstring1 recevra la valeur "d'ARTAGNAN" ?
    La solution donc est très simple, employez les variables de liaisons:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Insert intoValues (:b1, :b2:, b3) 
    ...
    Quand à l'utilité des tables temporaires afin «*des récupérer les données de mon curseur*» il y a du travail à la planche.

  5. #5
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    Merci pour vos réponses. Le REPLACE me semble être une bonne solution.
    Désolée pour la mise en page mais c'est mon premier post et je ne savais pas qu'on pouvait le faire ni comment le faire...

    Ensuite, mes questions vous ont sûrement paru bêtes mais je suis débutante et les enseignements des écoles sont loin d'être suffisants...
    En effet je n'ai même jamais entendu parler des variables de liaison, j'apprends au fur et à mesure. Travaillant sur un projet de grande ampleur avec beaucoup de choses déjà existantes, le problème de l'apostrophe a déjà été pensé je suppose et donc ce genre de valeur ne peut-être là.

    Pour ce qui est de la création de la table temporaire "à la volée", pas de problème car son nom est composé de multiples paramètres qui font qu'elle est unique et vu le nombre de tables à créer, il est impossible de créer une table définitive pour toutes les requêtes effectuées.

    Malheureusement, pour récupérer un DBMS_SQL_CURSOR dans un SYS_REFCURSOR, la seule fonction que j'ai trouvé ne fonctionne que sur oracle 11.g et nous sommes en 10.g d'où la table temporaire...

    Merci pour votre aide, je pense pouvoir m'en sortir avec vos indications

  6. #6
    Membre confirmé Avatar de NGasparotto
    Inscrit en
    Janvier 2007
    Messages
    421
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 421
    Points : 603
    Points
    603
    Par défaut
    Citation Envoyé par cocoaparis Voir le message
    Merci pour vos réponses. Le REPLACE me semble être une bonne solution.
    Ah bon ? Et si tes variables contiennent ', ,' ? Le NVL() propose fonctionne mieux.
    Variables de liaison = bind variables, peut-etre la solution la plus raisonnable.
    A moins qu le plus raisonnable soit de ne pas travailler avec des creation de table a la volee, meme avec tout ce que vous voudrez comme cle unique, rare (pour ne pas dire jamais) sont les cas ou ce ne peut pas etre remplacer par des GTT, ce qui a pour avatange majeur d'eviter le SQL dynamique, qui est veritable gegeure a debugger et maintenir.

    Citation Envoyé par cocoaparis Voir le message
    ...vu le nombre de tables à créer, il est impossible de créer une table définitive pour toutes les requêtes effectuées.
    Je ne connais pas les tenants et abouttissant des contraintes que tu as, tes specs etc, mais a lire ceci, je dirais qu'il y a un serieux probleme de conception alors, ou de comprehension de ce qu'est une base de donnees. Parce qu'enfin, que fait t'on avec le resultat d'un curseur dans une table ? Une autre requete avec curseur pour la lire ?

    Nicolas.

  7. #7
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    En effet, le nvl fonctionne très bien. C'est ce que je vais prendre comme solution...
    Le curseuest récupéré sur la couche business en .net sous forme de dataset pour au final être récupéré par un web service...
    Normalement, pour les autres requêtes que j'ai faites, je n'ai pas dû utiliser le dynamique ni la création de table temporaire.
    En l'occurrence, la longueur de la requête dépasse les 4000 caractères et on utilise donc un DBMS_SQL.varchar2A puis on construit notre requête en dynamique.
    Tout ceci est mis dans un DBMS_SQL.CURSOR, or on doit retourner un SYS_REFCURSOR. La fonction TO_REFCURSOR ne fonctionne pas sous oracle 10.g et à moins qu'il existe une possibilité pour faire ça sans passer par la création d'une table temporaire puis d'une vue dynamique, je fais comme ça car c'est la seule solution que j'ai trouvée ce qui ne m'enchante pas mais je n'ai pas le choix...

    Merci pour vos conseils

  8. #8
    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
    Non, ça à l'air de fonctionner très bien. Il y a des autres soucis liés aux requêtes SQL qui n'utilisent pas des variables de liaisons. Parfois il y a en a aussi pour ceux qui utilisent de variables de liaison d'où la nécessité de faire un choix avisé.
    Mais j'ai l'impression qu'il y en a un peu de confusion dans l'air. Si vous avez besoin d'un ref_curseur pourquoi vous n'utilisez pas un ref_curseur ? Il est possible d'un ouvrir avec du SQL dynamique.

  9. #9
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 24
    Points : 12
    Points
    12
    Par défaut
    J'ai en effet besoin d'un ref_curseur. Sur des requêtes qui ont été faites pas d'autres personnes, ils ont utilisé le dbms_sql.cursor pour le dynamique. Cependant, je pense que le problème vient surtout du fait que la requête est trop longue pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    OPEN curseur FOR vsqlselect
    d'où l'utilisation du DBMS_SQL.CURSOR.
    Mais merci pour le conseil

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

Discussions similaires

  1. [Elementum] Insertion de valeurs nulles dans une colonne numérique d'un table
    Par cquilgars dans le forum Autres outils décisionnels
    Réponses: 2
    Dernier message: 17/07/2012, 11h50
  2. Réponses: 2
    Dernier message: 08/03/2011, 11h53
  3. insérer la valeur null dans une colonne
    Par loic20h28 dans le forum C#
    Réponses: 12
    Dernier message: 27/05/2009, 11h21
  4. Réponses: 2
    Dernier message: 26/01/2009, 15h38
  5. Réponses: 5
    Dernier message: 11/07/2008, 08h37

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