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 :

ORA-01427: single-row subquery returns more than one row


Sujet :

SQL Oracle

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2006
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 236
    Points : 78
    Points
    78
    Par défaut ORA-01427: single-row subquery returns more than one row
    Lorsque je fais un update, j'obtiens cette erreur :
    ORA-01427: single-row subquery returns more than one row


    Voici ma requete:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    UPDATE FRH
    SET (STATUT_ID,SALARIE_ID) = (SELECT statut_id, salarie_id
    FROM frh f, salarie s
    WHERE s.sal_id=f.salarie_id
    AND f.statut_id IS NOT NULL
    AND f.temps_id = (select MAX(temps_id) from frh where frh.salarie_id=f.salarie_id and temps_id<= '31/12/2006' and frh.statut_id IS NOT NULL)
    )
    where (remu_id=4 or remu_id=3) and temps_id='31/12/2006'
    J'ai besoin de votre aide...

  2. #2
    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
    le SELECT de la sous-requête retourne plus d'une ligne (c'est ce que dit le message )

    il manque probablement une jointure avec la PK de FRH. Note qu'une fonction analytique est plus performante que la solution que tu as choisis

  3. #3
    Membre régulier
    Inscrit en
    Novembre 2006
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 236
    Points : 78
    Points
    78
    Par défaut
    Ce que je ne comprend pas c'est que ma requete renvoie qu'une donnée pour chaque salarie...

    Si je fais ca, j'ai la meme erreur..:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    UPDATE FRH
    SET (STATUT_ID,SALARIE_ID) = (SELECT distinct statut_id, salarie_id
    FROM frh f, salarie s
    WHERE s.sal_id=f.salarie_id
    AND f.statut_id IS NOT NULL
    AND f.temps_id = (select MAX(temps_id) from frh where frh.salarie_id=f.salarie_id and temps_id<= '31/12/2006' and frh.statut_id IS NOT NULL)
    )
    where salarie_id=(select salarie_id from frh where (remu_id=4 or remu_id=3) and temps_id='31/12/2006')

    Comment peut t'on lire qu'une ligne a la fois?

  4. #4
    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
    tu es dans un ensemble...

    Execute :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MAX(temps_id) FROM frh WHERE frh.salarie_id=f.salarie_id AND temps_id<= '31/12/2006' AND frh.statut_id IS NOT NULL
    Ca retourne bien plus d'une ligne non ? Il faut donc trouver comment joindre cette ensemble à celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT DISTINCT statut_id, salarie_id
    FROM frh f, salarie s
    WHERE s.sal_id=f.salarie_id
    AND f.statut_id IS NOT NULL
    encore une fois, avec la fonction analytique tu n'aurais pas ce problème

  5. #5
    Membre régulier
    Inscrit en
    Novembre 2006
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 236
    Points : 78
    Points
    78
    Par défaut
    Avec la fonction analytique, j'ai le meme souci...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    update frh
    set statut_id=(SELECT statut_id
    FROM (select salarie_id, statut_id, temps_id, ROW_NUMBER() OVER (PARTITION BY salarie_id ORDER BY temps_id DESC) num
    FROM frh f, salarie s
    WHERE s.sal_id=f.salarie_id
    AND f.statut_id IS NOT NULL
    AND temps_id <= '31/12/2006')
    WHERE num = 1)
    where salarie_id=(select salarie_id from frh where (remu_id=4 or remu_id=3) and temps_id='31/12/2006')

    C'est qd meme bizarre? J'oublie surement un truc mais quoi?

  6. #6
    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
    c'est pas bizarre, il suffit d'enlever FRH de la sous-requête ou ajouter une jointure sur la PK entre frh et f (FRH de la sous-requête)

    Sans la description des tables ça va être compliqué de t'aider

    En plus, je serais surpris que la requête de la clause WHERE de l'UPDATE ne retourne qu'une seule ligne

  7. #7
    Membre régulier
    Inscrit en
    Novembre 2006
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 236
    Points : 78
    Points
    78
    Par défaut
    Voici le contenu de ma table FRH

    Et en fait, j'aimerais mettre le statut au niveau de la ligne où remu_id=4 (avec des contraintes sur les dates pour compliquer les choses ).
    Images attachées Images attachées  

  8. #8
    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
    et pourquoi pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    UPDATE frh
    SET statut_id=(SELECT statut_id
    FROM (SELECT salarie_id, statut_id, temps_id, ROW_NUMBER() OVER (PARTITION BY salarie_id ORDER BY temps_id DESC) num
    FROM frh f, salarie s
    WHERE s.sal_id=f.salarie_id
    AND f.statut_id IS NOT NULL
    AND temps_id <= '31/12/2006'
    AND f.salrie_id=frh.salarie_id)
    WHERE num = 1)
    WHERE remu_id IN (3,4) AND temps_id='31/12/2006')
    Manque :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND f.salrie_id=frh.salarie_id
    Il faut absolument que la sous-requête retourne 1 seul résultat pour chaque salarié, il faut donc joindre la sous-requête à la table que tu mets à jour

    Dans la 1° sous-requête et la 2° sous-requête est inutile.

  9. #9
    Membre régulier
    Inscrit en
    Novembre 2006
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 236
    Points : 78
    Points
    78
    Par défaut
    Oui j'avais deja essayé ca, mais il me met:

    ORA-00904: "FRH"."SALARIE_ID": invalid identifier


    ????

  10. #10
    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
    ha oui

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    UPDATE FRH
    SET STATUT_ID=(SELECT statut_id
    							   FROM frh f
    								WHERE FRH.salarie_id=f.salarie_id
    									AND f.statut_id IS NOT NULL
    								  AND f.temps_id = (SELECT MAX(temps_id) 
    								                      FROM frh 
    								                     WHERE frh.salarie_id=f.salarie_id 
    								                       AND temps_id<= '31/12/2006' 
    								                       AND frh.statut_id IS NOT NULL)
    							)
    WHERE remu_id IN (3,4) AND temps_id='31/12/2006';
    Note que la table salarie ne sert à rien dans ton exemple a priori (à vérifier quand même )

  11. #11
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Attention si tu as 2 fois le même temps_id pour un salarié (dans ce cas la requete (select statut_id) renverra plusieurs lignes.
    Soit rajouter un ROWNUM = 1 sur cette requete

    Mieux : Utiliser le keep dense rank qui élimine la sous requete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    UPDATE FRH
    SET STATUT_ID=(SELECT MAX(statut_id)  KEEP (DENSE_RANK FIRST ORDER BY temps_id DESC)
    		FROM frh f
    		WHERE f.salarie_id=frh.salarie_id
    		AND f.statut_id IS NOT NULL
    		AND f.temps_id <= '31/12/2006' 
    		)
    WHERE remu_id IN (3,4) 
    AND temps_id='31/12/2006';

  12. #12
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 20
    Points : 23
    Points
    23
    Par défaut
    Salut,

    Je pense qu'il faut lier le premier appel à FRH du UPDATE au frh du sous-select :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    UPDATE FRH frh
    SET (STATUT_ID,SALARIE_ID) = (SELECT statut_id, salarie_id
    FROM frh f, salarie s
    WHERE s.sal_id=f.salarie_id
    AND f.statut_id IS NOT NULL
    AND frh.salarie_id = f.salarie_id
    AND f.temps_id = (SELECT MAX(temps_id) FROM frh f2 WHERE f2.salarie_id= f.salarie_id AND temps_id<= '31/12/2006' AND f2.statut_id IS NOT NULL)
    )
    WHERE (remu_id=4 OR remu_id=3) AND temps_id='31/12/2006'

  13. #13
    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 McM Voir le message
    Mieux : Utiliser le keep dense rank qui élimine la sous requete
    je l'oublie tout le temps celui-là

  14. #14
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Pas moi, il est dans mon fichier des requetes à ne pas oublier.

  15. #15
    Membre régulier
    Inscrit en
    Novembre 2006
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 236
    Points : 78
    Points
    78
    Par défaut
    MErci bcp ca fonctionne!!!

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

Discussions similaires

  1. Erreur ORA-01427 single-row subquery returns more than one row
    Par SmileAndFly dans le forum Langage SQL
    Réponses: 10
    Dernier message: 29/08/2008, 15h12
  2. Réponses: 5
    Dernier message: 01/02/2008, 10h07
  3. Réponses: 4
    Dernier message: 25/01/2007, 15h02
  4. Réponses: 3
    Dernier message: 08/12/2006, 17h28
  5. ORA-01427: single-row subquery returns more than one row
    Par hadid dans le forum Langage SQL
    Réponses: 3
    Dernier message: 31/10/2006, 15h35

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