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

Requêtes et SQL. Discussion :

Erreur lors de la conversion d'une requête SELECT en DELETE


Sujet :

Requêtes et SQL.

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 182
    Points : 139
    Points
    139
    Par défaut Erreur lors de la conversion d'une requête SELECT en DELETE
    Bonjour à tous,

    Voilà mon problème :
    Je voudrais faire une requête DELETE relativement compliquée (à mon goût).
    Pour ce faire, je passe par le QBE, je commence à faire une requête SELECT, pour être sûr que je prend bien les bons enregistrements.
    Jusque là, aucun soucis, tout fonctionne parfaitement bien.
    Le problême arrive quand je transforme ma requête SELECT en DELETE, lorsque j'exécute cette requête DELETE, Access me dit :
    "Impossible de supprimer dans les tables spécifiées."
    Selon l'aide d'Access, je n'aurais pas accès à mes tables... Or j'ai bien un accès complet.

    Voici ma requête SELECT :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT S_TRS_OAQ10.*
    FROM ((S_OAQ10 RIGHT JOIN S_TRS_OAQ10 ON S_OAQ10.CODE = S_TRS_OAQ10.CODE_OAQ10) LEFT JOIN S_CAG ON S_OAQ10.CODE = S_CAG.CODE_OAQ10) LEFT JOIN (S_TRS RIGHT JOIN S_TRS_CAG ON S_TRS.CLEF = S_TRS_CAG.CLEF_TRS) ON S_CAG.CLEF = S_TRS_CAG.CLEF_CAG
    WHERE (((S_TRS_CAG.CLEF_TRS)=[s_trs].[clef]));

    => Fonctionne super bien

    Une fois convertie en DELETE :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DELETE S_TRS_OAQ10.*, S_TRS_CAG.CLEF_TRS
    FROM ((S_OAQ10 RIGHT JOIN S_TRS_OAQ10 ON S_OAQ10.CODE = S_TRS_OAQ10.CODE_OAQ10) LEFT JOIN S_CAG ON S_OAQ10.CODE = S_CAG.CODE_OAQ10) LEFT JOIN (S_TRS RIGHT JOIN S_TRS_CAG ON S_TRS.CLEF = S_TRS_CAG.CLEF_TRS) ON S_CAG.CLEF = S_TRS_CAG.CLEF_CAG
    WHERE (((S_TRS_CAG.CLEF_TRS)=[s_trs].[clef]));

    Ne fonctionne pas du tout !
    C'est à ce stade que j'obtiens le message d'access :
    "Impossible de supprimer dans les tables spécifiées."


    Je ne suis pas un expert en jointures, loin de là, c'est la première fois que je les utilises.
    Bon, si ma requête SELECT ne fonctionnait pas, je me dirais que j'ai fait une erreur, mais la SELECT fonctionne parfaitement bien (enfin du moins elle en à l'air).

    Donc si une âme généreuse pouvait m'aider, je suis preneur.

    Merci d'avance à ceux qui m'aideront.

  2. #2
    Membre expérimenté
    Avatar de Mahefasoa
    Homme Profil pro
    Manager IT
    Inscrit en
    Octobre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Manager IT

    Informations forums :
    Inscription : Octobre 2003
    Messages : 835
    Points : 1 664
    Points
    1 664
    Par défaut
    Bonjour,
    Citation Envoyé par Devil-Atomic666
    Une fois convertie en DELETE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DELETE S_TRS_OAQ10.*, S_TRS_CAG.CLEF_TRS
    FROM ((S_OAQ10 RIGHT JOIN S_TRS_OAQ10 ON S_OAQ10.CODE = S_TRS_OAQ10.CODE_OAQ10) LEFT JOIN S_CAG ON S_OAQ10.CODE = S_CAG.CODE_OAQ10) LEFT JOIN (S_TRS RIGHT JOIN S_TRS_CAG ON S_TRS.CLEF = S_TRS_CAG.CLEF_TRS) ON S_CAG.CLEF = S_TRS_CAG.CLEF_CAG
    WHERE (((S_TRS_CAG.CLEF_TRS)=[s_trs].[clef]));
    Ne fonctionne pas du tout !
    Alors, DELETE est la clause d'une requête Action qui supprime des enregistrements contenus dans une table. Dans la clause FROM de ta requête, il y a association de plusieurs TABLES. Si la modification et/ou suppression en cascade a été activée dans la relation entre ces tables, peut-être cela ira-t-il mieux?
    Mais est-ce qu'il n'est pas possible d'avoir une requête dans le style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DELETE *
    FROM source
    WHERE critère;
    Ce que je veux dire par là, placer un critère correspondant à tes besoins en limitant au maximum l'écriture au niveau des clauses DELETE et FROM?
    Bon courage et @+
    La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici nous avons réuni théorie et pratique: Rien ne fonctionne ... et personne ne sait pourquoi!
    Albert Einstein

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 182
    Points : 139
    Points
    139
    Par défaut
    Merci Mahefasoa de m'avoir répondu si rapidement.

    La suppression en cascade est bien activée, mais je veux supprimer des données de ma dernière table, mais rien dans les autres, et pour arriver à cette dernière table (donc S_TRS_OAQ10), je suis obligé de passer par toutes les autres.

    Ce que je ne comprend pas, c'est que ma requête SELECT fonctionne très bien, mais quand je la transforme en DELETE à partir du QBE, ça ne fonctionne plus. Pourtant, puisque la SELECT fonctionne, en la transformant en DELETE, ça devrait fonctionner, non ?

    Peut être devrais-je garder ma requête SELECT, et créer une autre requête DELETE basée sur ma SELECT ? Je commence à m'embrouiller tout seul là !

  4. #4
    Membre expérimenté
    Avatar de Mahefasoa
    Homme Profil pro
    Manager IT
    Inscrit en
    Octobre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Manager IT

    Informations forums :
    Inscription : Octobre 2003
    Messages : 835
    Points : 1 664
    Points
    1 664
    Par défaut
    Bonjour,
    C'est que tu ne m'as pas compris.
    Citation Envoyé par Devil-Atomic666
    Ce que je ne comprend pas, c'est que ma requête SELECT fonctionne très bien, mais quand je la transforme en DELETE à partir du QBE, ça ne fonctionne plus. Pourtant, puisque la SELECT fonctionne, en la transformant en DELETE, ça devrait fonctionner, non ?
    Ce n'est pas parce qu'avec SELECT cela a super bien fonctionné que cela devrait l'être avec DELETE!
    Tu ne m'as pas suivi dans ma proposition d'hier:
    Citation Envoyé par Mahefasoa
    Mais est-ce qu'il n'est pas possible d'avoir une requête dans le style
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    DELETE * FROM source WHERE critère;
    Ce que je veux dire par là, placer un critère correspondant à tes besoins en limitant au maximum l'écriture au niveau des clauses DELETE et FROM?
    Alors ce que je veux te proposer nécessite l'utilisation d'une sous-requête, ce qui me paraît inévitable. Voic donc une proposition d'un code SQL en modifiant ton code d'origine.
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    DELETE S_TRS_OAQ10.*
    FROM S_TRS_OAQ10
    WHERE S_TRS_OAQ10.[La clé primaire] IN (SELECT S_TRS_OAQ10.[La clépri maire] FROM ((S_OAQ10 RIGHT JOIN S_TRS_OAQ10 ON S_OAQ10.CODE = S_TRS_OAQ10.CODE_OAQ10) LEFT JOIN S_CAG ON S_OAQ10.CODE = S_CAG.CODE_OAQ10) LEFT JOIN (S_TRS RIGHT JOIN S_TRS_CAG ON S_TRS.CLEF = S_TRS_CAG.CLEF_TRS) ON S_CAG.CLEF = S_TRS_CAG.CLEF_CAG WHERE (((S_TRS_CAG.CLEF_TRS)=[s_trs].[clef])));
    J'ai transofrmé ta requête en requête SELECT SQL que j'ai mis comme sous-requête (en gras dans le code) de la requête DELETE et ainsi je n'ai que DELETE ... FROM ... WHERE. Toute la sélection se trouve dans cette dernière clause.
    Remarques que dans la clause SELECT de la sous-requête, j'ai omis l'autre champ S_TRS_CAG.CLEF_TRS.
    Le principe est le suivant: supprimer tous les enregistrements de la table S_TRS_OAQ10 correspondant aux enregistrements sélectionnés dans la sous-requête.
    J'espère t'avoir donné une idée. Sinon, dans la ou sur le forum, on en parle beaucoup des sous-requêtes.
    Enfin ce que je peux te dire c'est que ce n'est pas le top coté performance.
    Bon courage et @+
    La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici nous avons réuni théorie et pratique: Rien ne fonctionne ... et personne ne sait pourquoi!
    Albert Einstein

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour

    Est-ce des tables Access ou des tables liées à une autre base ?

    Si c'est une autre base, tu peux toujours lire (Select), mais es-tu sûr de pouvoir écrire ou supprimer dessus ?

    Starec

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 182
    Points : 139
    Points
    139
    Par défaut
    Mahefasoa, j'essaye de faire comme tu me dis dès lundi matin, je n'avais effectivement pas compris ce que tu voulais m'expliquer comme il aurait fallut que je le comprenne !

    Starec, ce sont effectivement des tables liées, mais je suis sûr d'avoir un accès total, il n'y a aucun problème de ce côté.

    Merci à vous deux ! Je vous tiens au courant dès que j'ai testé.

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 182
    Points : 139
    Points
    139
    Par défaut
    Bonjour à tous,

    En ce début de semaine, je viens de tester la requête sql de Mahefasoa :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DELETE S_TRS_OAQ10.*
    FROM S_TRS_OAQ10
    WHERE S_TRS_OAQ10.[CLEF_TRS] IN (SELECT S_TRS_OAQ10.[CLEF_TRS] FROM ((S_OAQ10 RIGHT JOIN S_TRS_OAQ10 ON S_OAQ10.CODE = S_TRS_OAQ10.CODE_OAQ10) LEFT JOIN S_CAG ON S_OAQ10.CODE = S_CAG.CODE_OAQ10) LEFT JOIN (S_TRS RIGHT JOIN S_TRS_CAG ON S_TRS.CLEF = S_TRS_CAG.CLEF_TRS) ON S_CAG.CLEF = S_TRS_CAG.CLEF_CAG WHERE (((S_TRS_CAG.CLEF_TRS)="06/07/2007-B-B02")));

    Résultat : ça fonctionne parfaitement bien !!!

    Ma plus grosse erreur fut de croire que transformer une requête SELECT en requête DELETE allait fonctionner correctement, ce qui n'est pas le cas .

    Il va donc falloir que je me penche un peu plus sur ces requêtes, je suis loin d'être au top !!!

    Merci beaucoup Mahefasoa

    Par contre :
    Citation Envoyé par Mahefasoa
    Enfin ce que je peux te dire c'est que ce n'est pas le top coté performance.
    Il y aurait-il une autre solution ?

    Cordialement,
    Devil-Atomic666

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 182
    Points : 139
    Points
    139
    Par défaut
    Bonjour tout le monde,

    Je reviens sur ce sujet, car je viens de me rendre compte que ma dernière requête ne fonctionne pas ! En fait, j'ai été un peu vite, voyant que la requête se lançait et supprimait les bons enregistrements, je n'ai pas remarqué qu'elle en supprimait en fait trop !

    Donc après toute une matinée de tests je me retrouve maintenant avec cette requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    DELETE *
    FROM H_TRS_OAQ10
    WHERE (H_TRS_OAQ10.CLEF_TRS="07/07/2007-A-B02") And (H_TRS_OAQ10.CODE_OAQ10=(SELECT H_TRS_OAQ10.CODE_OAQ10
    FROM ((H_OAQ10 INNER JOIN H_TRS_OAQ10 ON H_OAQ10.CODE=H_TRS_OAQ10.CODE_OAQ10) INNER JOIN H_CAG ON H_OAQ10.CODE=H_CAG.CODE_OAQ10) INNER JOIN (H_TRS INNER JOIN H_TRS_CAG ON H_TRS.CLEF=H_TRS_CAG.CLEF_TRS) ON H_CAG.CLEF=H_TRS_CAG.CLEF_CAG
    WHERE H_TRS.CLEF="07/07/2007-A-B02" AND H_TRS_OAQ10.CLEF_TRS="07/07/2007-A-B02"));

    Et lorsque je l'exécute, voici le message que j'obtiens :
    Citation Envoyé par Access
    Cette sous-requête peut retourner au plus un enregistrement.
    Pourtant, lorsque j'exécute la sous-requête seule, j'obtiens bien plusieurs enregistrements (et les bons en plus !).
    Alors, un ptit coup de , je vais lire l'aide d'Access, et voilà ce que j'obtiens :
    Citation Envoyé par Access
    Cette sous-requête peut retourner au plus un enregistrement. (Erreur 3354)
    Une sous-requête de ce type ne peut renvoyer plus d'un seul enregistrement. Corrigez l'instruction SELECT de la sous-requête pour demander un seul enregistrement.
    Et alors là, soit je ne comprend pas bien l'aide, soit il y a une erreur dedans. Enfin, moi je comprend que cette sous-requête ne peut renvoyer que un seul enregistrement maximum, et qu'il faut que je corrige pour qu'elle ne renvoie qu'un seul enregistrement... !

    Donc, sachant que ma sous-requête seule renvoie bien le bon nombre d'enregistrement, comment se fait-il que je n'arrive pas à l'inclure dans ma requête DELETE ? Que fais-je donc de travers ???

    Merci à tout ceux qui auront lu cette question, et merci d'avance à ceux qui pourront m'aider.
    Cordialement,
    Devil-Atomic666

  9. #9
    Membre expérimenté
    Avatar de Mahefasoa
    Homme Profil pro
    Manager IT
    Inscrit en
    Octobre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Manager IT

    Informations forums :
    Inscription : Octobre 2003
    Messages : 835
    Points : 1 664
    Points
    1 664
    Par défaut
    Bonjour,
    Un tout petit petit petit cours qui n'a pas la prétention de l'être pour commencer.
    Imaginons que la clause WHERE de la requête contient le critère suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    WHERE [champ]=valeur
    Au cas où le champ doit correspondre à plusieurs valeurs, on peut écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    WHERE [champ]=valeur1 OR [champ]=valeur2 ...
    'ou
    WHERE [champ] IN (valeur1,valeur2,...)
    Dans le cadre de l'utilisation d'une sous-requête dans une clause WHERE d'une requête SQL, si la sous-requête retourne un seul enregistrement en théorie, la syntaxe suivante suffit à la faire fonctionner:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    WHERE [champ]=(SELECT champx FROM tablex WHERE chapx=valeurx)
    Mais cela n'est jamais certain et il est presque toujours vrai que la sous-requête puisse retourner plusieurs enregistrements alors dans ce cas, l'utilisation de IN est requise, comme le montre cet exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    WHERE [champ] IN (SELECT champx FROM tablex WHERE chapx=valeurx)
    Si jamais j'ai écris une tâche (par ignorance ou par inadvertance), j'en suis vraiment désolé et j'invite tout ce qui s'en aperçoit à la corriger. Merci.
    Bref, voila l'explication, je ne sais pas si cela est à ta convenance.
    Essayes donc de modifier ton code comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DELETE *
    FROM H_TRS_OAQ10
    WHERE (H_TRS_OAQ10.CLEF_TRS="07/07/2007-A-B02") AND (H_TRS_OAQ10.CODE_OAQ10 IN (SELECT H_TRS_OAQ10.CODE_OAQ10
    FROM ((H_OAQ10 INNER JOIN H_TRS_OAQ10 ON H_OAQ10.CODE=H_TRS_OAQ10.CODE_OAQ10) INNER JOIN H_CAG ON H_OAQ10.CODE=H_CAG.CODE_OAQ10) INNER JOIN (H_TRS INNER JOIN H_TRS_CAG ON H_TRS.CLEF=H_TRS_CAG.CLEF_TRS) ON H_CAG.CLEF=H_TRS_CAG.CLEF_CAG
    WHERE H_TRS.CLEF="07/07/2007-A-B02" AND H_TRS_OAQ10.CLEF_TRS="07/07/2007-A-B02"));
    Bon courage et @+
    La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici nous avons réuni théorie et pratique: Rien ne fonctionne ... et personne ne sait pourquoi!
    Albert Einstein

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 182
    Points : 139
    Points
    139
    Par défaut
    Hum... Je ne connaissais pas ce 'IN'... ... Il est vrai que je ne suis pas un expert du SQL, loin de là !

    Merci énormément Mahefasoa ! Comme quoi, on en apprend tout les jours ! Quand je pense que je viens de passer plusieurs heures sur ce petit truc !

    Bon maintenant ma requête à l'air de bien fonctionner, mais je vais quand même tester plus en détail pour en être vraiment sûr cette fois !

    Cordialement,
    Devil-Atomic666

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

Discussions similaires

  1. Réponses: 15
    Dernier message: 02/06/2010, 15h08
  2. Erreur lors de l'exécution d'une requête avec ADOquery
    Par doolar dans le forum Bases de données
    Réponses: 2
    Dernier message: 03/05/2008, 13h26
  3. [PostgreSQL] [PostGreSQL] Obtention d'une erreur lors de l'exécution d'une requête
    Par cbombabill dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 06/03/2008, 11h56
  4. Réponses: 6
    Dernier message: 13/12/2007, 03h13
  5. [MySQL] Erreur lors de la construction d'une requête
    Par gaetan24 dans le forum PHP & Base de données
    Réponses: 23
    Dernier message: 06/04/2007, 15h45

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