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

SQL Oracle Discussion :

Vérifier l'existence d'un enregistrement [11gR1]


Sujet :

SQL Oracle

  1. #1
    Membre régulier
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2012
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2012
    Messages : 77
    Points : 85
    Points
    85
    Par défaut Vérifier l'existence d'un enregistrement
    Bonjour,

    Je suis actuellement bloquée sur un ordre SQL simple ayant une réaction assez imprévue.

    Je récupère des données à intégrer dans ma base Oracle depuis un fichier XML. Dans ce fichier j'ai des informations concernant des dossiers qui peuvent déjà exister dans ma base et auquel cas je dois faire des mises à jour, ou alors des dossiers qui n'existent pas encore et que je dois créer.

    Je fais donc un select pour récupérer l'ID de dossier dans ma base, si il existe, correspondant aux données que je récupère:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT DISTINCT
    CASE WHEN EXISTS(SELECT ID_DOSSIER FROM TableDossier
                               WHERE TableDossier.DOSSIERNOM = 'toto') -- toto est une valeur unique, il ne peut y avoir de doublon
        THEN 1
        ELSE 0
    END 
    INTO v_exist
    FROM DUAL;
     
    IF v_exist=0 THEN
    --Le dossier n'existe pas, je dois le créer
    ELSE
    --Le dossier existe, je dois le mettre à jour
    END IF;
    Lorsque le dossier n'existe pas, tout fonctionne parfaitement : création du dossier, remplissage des tables liées, etc.

    Mais lorsque le dossier existe déjà, je me retrouve avec une erreur de type TOO_MANY_ROWS.
    Alors bon, j'ai bien pensé à faire un catch sur l'erreur et effectuer le traitement de mise à jour quand je la récupère mais, c'est môôôôôôche!!

    Bref, je me retrouve un peu perdue face à ce comportement.

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    la requete est mal faites :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT ma_col into ma_var from dual where exists (......)

    Sinon regardez du côté de l'instruction MERGE

  3. #3
    Membre régulier
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2012
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2012
    Messages : 77
    Points : 85
    Points
    85
    Par défaut
    J'essaye donc ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT ID_DOSSIER INTO v_id_dossier FROM DUAL
    WHERE EXISTS(SELECT ID_DOSSIER FROM TableDossier
    	 WHERE TableDossier.DOSSIERNOM = 'toto');
    Par contre j'ai une erreur d'identificateur non valide concernant ID_DOSSIER (en gras).
    Le FROM DUAL me perturbe, que met-on comme champ après le SELECT?

    --
    Edit : Lorsque je fais un select *, j'obtiens à nouveau l'erreur TOO_MANY_ROWS

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    En fait, votre 1ere approche est ok, j'ai mal cerné le problème.

    Le too_many_row ne viendrait-il pas plutôt des actions que vous n'avez pas montré dans la partie "mise à jour" de votre code ?

  5. #5
    Membre régulier
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2012
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2012
    Messages : 77
    Points : 85
    Points
    85
    Par défaut
    Dans la partie de mise à jour (ELSE) je récupère l'id du dossier et je fais un insert dans une autre table. Quand je dis mise à jour, en fait je ne passe pas par un update, il n'y a pas de MAJ de table. C'est d'un point de vue fonctionnel qu'il y a une mise à jour.
    Et donc je créé une ligne dans une table qui a besoin de mon id_dossier comme FK.

    Voici mon code:
    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
    SELECT DISTINCT
    CASE WHEN EXISTS(SELECT ID_DOSSIER FROM tableDossier
                     WHERE tableDossier.DOSSIERNOM = 'toto')
      THEN 1
      ELSE 0
    END 
    INTO v_exist
    FROM DUAL;
     
    IF v_exist=0 THEN
    -- création du dossier et insertion
     
    ELSE
      -- Récupération de l'id du dossier
      SELECT ID_DOSSIER INTO v_id_dossier FROM tableDossier
      WHERE tableDossier.DOSSIERNOM = 'toto'); --Le même select que dans la vérification
     
      -- Le dossier existe : je créé une ligne dans une table nécessitant l'id du dossier
      INSERT
        INTO tableLiee
        (ID_DOSSIER
        ,ID_tableLiee)
      SELECT
        v_id_dossier
        ,schema.sequence.nextval
      FROM DUAL;
     
    END IF;
    --
    Je viens de refaire la manip:
    1/ Je vide ma base puis je lance mon script : le dossier n'existe pas donc il le créé et rempli les tables liées.
    2/ Je relance mon script : Le dossier existe déjà (puisque je viens de le créer). --> ORA-01422 : l'extraction exacte ramène plus que le nombre de lignes demandées.

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    oki.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT ID_DOSSIER INTO v_id_dossier FROM tableDossier
      WHERE tableDossier.DOSSIERNOM = 'toto'
    Ceci doit ramener plus d'une ligne je suppose.

    Faites un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    select count(*) FROM tableDossier
      WHERE tableDossier.DOSSIERNOM = 'toto'
    pour vérifier.

  7. #7
    Membre régulier
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2012
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2012
    Messages : 77
    Points : 85
    Points
    85
    Par défaut
    Pourtant le count(*) me confirme qu'il n'y a qu'une seule ligne correspondant à ma recherche.

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 772
    Points : 52 732
    Points
    52 732
    Billets dans le blog
    5
    Par défaut
    Pourquoi toute cette salade ? faite l'update en premier et l'insert en second. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE TableDossier
    SET ...
    WHERE DOSSIERNOM = 'toto';
    si toto n'existe pas aucune ligne n'est mise à jour.
    donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IF SQL%ROWCOUNT = 0
    ...
    INSERT INTO TableDossier ...
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  9. #9
    Membre régulier
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2012
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2012
    Messages : 77
    Points : 85
    Points
    85
    Par défaut
    Je n'ai pas d'update en fait, quand je disais mise à jour, c'était d'un point de vue fonctionnel, concernant un dossier.
    Je ne fais que des insert.

    En fait je reçois un fichier xml contenant des données à intégrer dans ma base oracle.
    Ces données concernent un dossier qui existe déjà ou qui est a créer (table dossier).
    Dans le cas où le dossier existe déjà, je dois intégrer une ligne dans la table service correspondant à ce dossier (en récupérant la FK-id_dossier).

    Donc je vérifie d'abord l’existence du dossier ou non dans la table dossier.
    - Si le dossier n'existe pas, je l'ajoute dans la table dossier puis je rempli plusieurs autres tables correspondantes (dont la table service).
    - Si le dossier existe déjà, je récupère l'id du dossier (qui n'apparaît pas dans mon xml, je n'ai que son nom, d'où le select) et j'insère une ligne dans la table service (avec l'id_dossier en FK).

  10. #10
    Membre régulier
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2012
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2012
    Messages : 77
    Points : 85
    Points
    85
    Par défaut
    Je procède par élimination en changeant certaines parties de code en commentaires et il semblerait que mon code soit bon. Cela vient d'un autre morceau qui fonctionne parfaitement seul mais qui ne doit pas supporter la cohabitation.

    Merci pour les conseils et les idées, ça m'a tout de même permis d'avancer!

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

Discussions similaires

  1. Vérifier l'existance d'un enregistrement dans un table
    Par toutoune95800 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 10/06/2013, 12h06
  2. Vérifier l'existence de mes enregistrements par un SELECT
    Par boutmos dans le forum Langage SQL
    Réponses: 6
    Dernier message: 17/09/2010, 23h17
  3. [MySQL] vérifier l'existance d'un enregistrement avant insertion
    Par patheoson dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 22/01/2010, 12h47
  4. vérifier l'existence d'un enregistrement
    Par haymen dans le forum C#
    Réponses: 11
    Dernier message: 09/01/2010, 14h04
  5. [AC-2003] Vérifier l'existence d'un enregistrement : DLookUp ou Select
    Par buzz73 dans le forum IHM
    Réponses: 2
    Dernier message: 22/07/2009, 13h31

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