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 Firebird Discussion :

update et jointure


Sujet :

SQL Firebird

  1. #1
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    479
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 479
    Points : 267
    Points
    267
    Par défaut update et jointure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    update client
    set 	a.type_client	=	b.type_client
    from client a,vs_contrimm b
    where a.code_client=b.code_client
    Voici un Update qui marche fort bien avec Sybase par exemple et qui sauf erreur de ma part ne sort pas des spécifications SQL standard.

    Quelle est la syntaxe permettant de faire le même type d'opérations avec Interbase ?

    (message d'erreur : token unknown from)

    Message édité par Barbibulle : Merci d'utiliser les balises "Code" pour une meilleur lecture de vos messages.

  2. #2
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut Re: update et jointure
    Je ne sais pas si votre ordre fonctionne bien sous SyBase mais la norme SQL veut dans ce cas là qu'on utilise un sous select.
    Et celà s'écrit comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    update client
      set a.type_client = (select b.type_client
                             from client a,vs_contrimm b
                             where a.code_client=b.code_client)

  3. #3
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    479
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 479
    Points : 267
    Points
    267
    Par défaut update et jointure
    Sur Sybase ça a bien marché pendant un an toute les nuits.

    Cela dit la syntaxe proposée renvoie le message "multiple rows un singleton select" sur Interbase car dans ce cas la clause select remplace une valeur constante qui va être affectée à toutes les lignes de la table client.

    Cela n'est pas ce que je souhaite. je souhaite faire une jointure qui permet de donner des valeurs différentes à chaque ligne concernée de la table client.

    Il faut donc nécessairement que la table client possède une clause where dans la clause update.

    Dans le sujet curseur j'explique comment j'ai résolu le problème.

  4. #4
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut Re: update et jointure
    Citation Envoyé par frantzgac
    Sur Sybase ça a bien marché pendant un an toute les nuits.
    Ah donc si c'est pas une erreur de frappe de votre part et que ca fonctionne sous Sybase, sachez que ce n'est pas une commande normalisé SQL (du moins pas à ma connaissance). De plus je ne comprend pas bien comment celà marche ou du moins ce que celà est censé faire.

    Citation Envoyé par frantzgac
    Cela dit la syntaxe proposée renvoie le message "multiple rows un singleton select" sur Interbase car dans ce cas la clause select remplace une valeur constante qui va être affectée à toutes les lignes de la table client.
    Oui bien entendu il faut que le sous select ne renvoie qu'une seule valeur (donc en général sa clause where attaque la clé primaire)

    Citation Envoyé par frantzgac
    Cela n'est pas ce que je souhaite. je souhaite faire une jointure qui permet de donner des valeurs différentes à chaque ligne concernée de la table client.

    Il faut donc nécessairement que la table client possède une clause where dans la clause update.

    Dans le sujet curseur j'explique comment j'ai résolu le problème.
    Je vais regarder le sujet Curseur car là j'avoue ne pas comprendre ce que vous voulez faire.
    Un update de la colonne type_client de la table client mais avec plusieures valeurs ?? Bref c'est pas bien clair.

  5. #5
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    479
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 479
    Points : 267
    Points
    267
    Par défaut
    c'est simple

    voici la table client
    code-client type client
    0, null
    1, null
    2, C

    voici la table conrimm
    code-client type client
    0,A
    1,X
    2,Z

    Lorsque la requête sera executée j'aurai une table client comme cici
    code-client type client
    0, A
    1, X
    2, Z

    Il s'agit d'une mise à jour avec jointure. Je ne sais toujours pas si cela peut se faire avec Interbase d'ailleurs.

    Cela dit le problème est résolu avec un for select et une procédure d'usage éphemère.

    ps : je ne comprends pas l'allusion à une faute de frappe.

  6. #6
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Citation Envoyé par frantzgac
    ps : je ne comprends pas l'allusion à une faute de frappe.
    C'est que je pensais au départ que vous aviez fait une faute de frappe car la syntaxe que vous utiliser ne fait pas partie de la norme SQL.

    Et je maintient ce que j'ai dit au départ (après relecture je m'apperçois que j'ai fait une erreur) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    update client a
      set a.type_client = (select b.type_client 
                             from vs_contrimm b 
                             where a.code_client=b.code_client)
    Celà est plus à la norme SQL.
    Et donc cette update fonctionnera uniquement si le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select b.type_client 
                             from vs_contrimm b 
                             where a.code_client=b.code_client
    ne retourne qu'une seule valeur.
    Ce qui est le cas dans votre exemple.

  7. #7
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    479
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 479
    Points : 267
    Points
    267
    Par défaut
    Euh non pas tout à fait, dans mon exemple on a trois mises à jour successives parce que la jointure envoie trois valeurs qui servent d'index à la mise à jour.

    Quelle est à votre avis la synatxe permettant de faire cela en Interbase ?

    J'a essayé ceci

    update client contrimm
    set client.type_client=contrimm.type_client
    where client.code_client=contrimm.code_client

    qui ne déclenche pas de message d'erreur mais ne fait pas non plus la mise à jour.

  8. #8
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Je maintiens ce que j'ai dit l'update que je vous ai donné fonctionne parfaitement avec le jeux de données que vous avez donné.

    car le sous select :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select b.type_client 
                             from vs_contrimm b 
                             where a.code_client=b.code_client
    retrourne qu'une et une seule valeur par ligne a mettre a jour(par code_client dans votre cas).

    Si l'update que je vous ai donné ne fonctionne pas et notamment donne le message d'erreur : "multiple rows un singleton select"
    C'est qu'il y a des doublons (sur la colonne code_client) dans votre table vs_contrimm. Dans ce cas le SGBD ne sais pas faire et plutot que d'affecter une des valeurs possible vous indique qu'il y a un probleme.

  9. #9
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    479
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 479
    Points : 267
    Points
    267
    Par défaut
    UPDATE titres
    SET cumulannuel_ventes = cumulannuel_ventes qt
    FROM titres, ventes
    WHERE titres.id_titre = ventes.id_titre
    AND ventes.date_cmd in (SELECT MAX(ventes.date_cmd) FROM ventes)

    voici un exemple similaire extrait d'un cours Transac-SQL qui parait il est compatible avec Oracle et MS-SQL ce qui n'est déjà pas mal...

  10. #10
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    479
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 479
    Points : 267
    Points
    267
    Par défaut
    Je vois ce que vous voulez dire concernant les doublons. Toutefois il faut bien dans la clause update (et en dehors du sous select) savoir quelle est la table correspondante au champ de contrimm servant à la mise à jour.

    Par conséquent où doit être indiqué le nom de la table contrimm ?

    update client contrimm ne fait pas d'erreur mais ne met pas à jour
    la clause from n'existe pas dans update interbase
    update client,contrimm provoque une erreur de syntaxe

  11. #11
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Le probleme c'est que vous n'essayez même pas les solutions qu'on vous donnes donc à quoi ca sert de continuer ??

    Je vais tout de même expliquer cet ordre SQL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    update client a 
      set a.type_client = (select b.type_client 
                             from vs_contrimm b 
                             where a.code_client=b.code_client)
    Que voulez vous mettre à jour ?
    réponse : la colonne Type_client de la table client.
    Ceci peut être fait comme grace à un update:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE CLIENT 
     SET TYPE_CLIENT = 'A';
    Cette commande va mettre un A à tout les types_client de la table client...
    Jusque là c'est simple.
    Mais ce c'est pas ce que vous cherchez. Vous voulez que type_client prenne la valeur de la colonne type_client de la table vs_contrimm qui a le même code_client.

    Comment rechercher la valeur type_client de la table vs_contrimm pour le client ayant le code_client=1 ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select b.type_client from vs_contrimm where b.Code_client=1
    Donc pour mettre à jour le client ayant le code 1 il faudrait faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE CLIENT A
      SET TYPE_CLIENT=(Select b.type_client from vs_contrimm where b.Code_client=1)
    WHERE CODE_CLIENT=1
    L'inconvéniant c'est qu'il faut faire autant d'update qu'il y a de client.
    Heureusement dans le sous-select on peut utiliser les valeurs donnés par le UPDATE avant la mise à jour de chaque enregistrement et celà devient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    update client a 
      set a.type_client = (select b.type_client 
                             from vs_contrimm b 
                             where a.code_client=b.code_client)
    le (select b.type_client from vs_contrimm b where a.code_client=b.code_client) étant exécuté pour chaque ligne client à mettre à jour et ne doit retourner qu'une seule valeur par code_client, ce qui le cas ici.

  12. #12
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Citation Envoyé par frantzgac
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    update  client contrimm
    set client.type_client=contrimm.type_client
    where  client.code_client=contrimm.code_client
    qui ne déclenche pas de message d'erreur mais ne fait pas non plus la mise à jour.
    Si il met à jour mais pas avec les valeurs que vous voulez. Votre ordre SQL est strictement equivallent à celui ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    update  client 
    set client.type_client = client.type_client

  13. #13
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    479
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 479
    Points : 267
    Points
    267
    Par défaut Pro
    Je ne vous permet pas de dire que je n'essaie pas ce qu'on me propose. C'est faux et discourtois. Vous êtes modérateur, par conséquent le moins serait que vous vous modériez vous même.

    Je demande à la cantonnade s'il est possible de faire un update avec jointure sur 2 tables avec Interbase et il est possible que vous n'ayez pas la réponse, inutile de s'en prendre les uns aux autres.

    Dire que ceci

    update client contrimm
    set client.type_client=contrimm.type_client
    where client.code_client=contrimm.code_client

    est équivalent à cela

    update client
    set client.type_client = client.type_client

    me parait polémique et non technique.

    Merci à vous

  14. #14
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut Re: Pro
    Citation Envoyé par frantzgac
    Je ne vous permet pas de dire que je n'essaie pas ce qu'on me propose. C'est faux et discourtois. Vous êtes modérateur, par conséquent le moins serait que vous vous modériez vous même.
    Et bien alors si vous essayez ce qu'on vous propose pourquoi ne remontez vous pas le fruit de vos essais ???? Et continuez comme si on avait rien proposé ? Si ce n'est pas de la discourtoisie, je ne m'y connais pas. Commencez donc par votre courtoisie et je m'occuperai de la mienne.

    Si j'en suis arrivé à cette conclusion, c'est à cause de votre attitude, j'en suis désolé, c'est une constatation.
    Relisez bien attentivement tout ce fil de conversation plutot que de prendre la mouche, vous verez que toutes les reponses s'y trouvent.

    Avouez qu'il est assez ennervant pour une personne qui aide les autres que celui qui pose une question ne tienne pas compte des réponses ou du moins ne dise pas ce qui va ou ne va pas dans ce qui est proposé...

    Maintenant je suppose que l'incident est clos, si vous voulez continuer de parler du probleme non technique de courtoisie veuillez m'envoyer un message privé, car celà polue innutilement le forum et n'interresse personne ici bas.

    Citation Envoyé par frantzgac
    Je demande à la cantonnade s'il est possible de faire un update avec jointure sur 2 tables avec Interbase et il est possible que vous n'ayez pas la réponse, inutile de s'en prendre les uns aux autres.
    La réponse a déjà été donné précédemment...
    NON, car la commande que vous avez donné ne fait pas parti de la norme SQL, elle est ppeut etre implémenté dans Sybase mais pas dans interbase/firebird.

    Citation Envoyé par frantzgac
    Dire que ceci

    update client contrimm
    set client.type_client=contrimm.type_client
    where client.code_client=contrimm.code_client

    est équivalent à cela

    update client
    set client.type_client = client.type_client

    me parait polémique et non technique.
    Il serait bon que vous utilisez les balises code lorsque vous ecrivez du code pour améliorer la lisibilité. Comme je vous l'ai déjà signalé dans votre premier message que j'ai du éditer. Mais vous persistez soit à m'ignorer soit à lire.

    En ce qui concerne les deux ordres SQL, ils sont bien equivallents, c'est la triste vérité, si vous ne le comprennez pas, demandez pourquoi ils sont equivallents plutot que de dire que c'est faux...

    Il ne faudrait pas inverser les roles, c'est vous qui avez un probleme, et qui posez des questions.

  15. #15
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    479
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 479
    Points : 267
    Points
    267
    Par défaut
    Inverser les rôles c'est vide dit et crée un présupposé sur nos rôles respectifs que je ne suis pas certain d'agréer. Jusqu'à preuve du contraire, nous sommes égaux.

    Je pose en effet des questions, mais je ne lis que des critiques sur ma formulation et non des réponses aux questions posées. C'est une méthode hélàs courante quand on a pas la réponse de dire que la question est mal posée.

    J'ai résolu mon problème mais je reste curieux de savoir si j'aurais pu faire autrement et par conséquent en effet j'attends que vous
    m'expliquiez en quoi

    update client contrimm
    set client.type_client=contrimm.type_client
    where client.code_client=contrimm.code_client

    est équivalent à cela

    update client
    set client.type_client = client.type_client

  16. #16
    Membre averti
    Avatar de Superstivix
    Inscrit en
    Décembre 2003
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 250
    Points : 405
    Points
    405
    Par défaut
    bonjour,

    votre question porte sur ce code qui ne me parait pas non plus (comme mon collègue) respecter le standard SQL!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    update client
    set 	a.type_client	=	b.type_client
    from client a,vs_contrimm b
    where a.code_client=b.code_client
    Je travaille sur MS_SQL et la requete se rapprochant le plus à la votre est la suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE client
    SET              type_client = vs_contrimm.type_client
    FROM         vs_contrimm
    WHERE     client.CLE = vs_contrimm.CLE
    Cette requete fonctionne très bien sous SQL_server, essayez là sous Interbase!

    En espérant vous avoir aidé

    Cordialement
    Superstivix
    Modérateur Taverne et C++Builder
    Règles du Club - Règles de la Taverne
    FAQ BCB - sources
    Et je mords

  17. #17
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Hélas comme je l'ai déjà signalé (en donnant le seul moyen SQL accepté par interbase pour ce type de mise à jour) on ne peux pas faire ça avec interbase.

    La solution est celle que j'ai donnée, c'est à dire d'utiliser un sous-select.
    Mais ce n'est pas l'avis de tous apparemment
    Sinon il y a aussi la solution de le faire via une procédure stoquée, mais ce n'est pas ce qui est demandé ici.

    Par contre sous MS_server que fait cet ordre dans le cas ou dans vs_contrimm il y a plusieurs enregistrements correspondant à une CLE client ? Une erreur ? Si non quel enregistrement est pris en compte pour le mise à jour ?

  18. #18
    Membre averti
    Avatar de Superstivix
    Inscrit en
    Décembre 2003
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 250
    Points : 405
    Points
    405
    Par défaut
    Citation Envoyé par Barbibulle
    Par contre sous MS_server que fait cet ordre dans le cas ou dans vs_contrimm il y a plusieurs enregistrements correspondant à une CLE client ? Une erreur ? Si non quel enregistrement est pris en compte pour le mise à jour ?
    Non pas d'erreur, l'update s'effectue correctement!
    L'enregistrement pris pour la mise à jour est le dernier trouvé lorsqu'on fait un SELECT * FROM vs_contrimm.
    Modérateur Taverne et C++Builder
    Règles du Club - Règles de la Taverne
    FAQ BCB - sources
    Et je mords

  19. #19
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Donc c'est à utiliser en connaissance de cause.

    S'il n'y a pas d'erreur c'est qu'il fait bien une jointure et il doit faire un UPDATE par ligne jointe.

    Ce qui veux dire que si une cle cliente à 100 000 référence dans vs_contrimm il y aura 100 000 update sur le même client (s'écrasant la même valeur à chaque fois)

    Il ne me semble pas que cette syntaxe fasse partie d'une des normes SQL. Mais je me trompe peut être.

    Ce qui est certain c'est que ce n'est pas implémenté dans Interbase.

  20. #20
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    479
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 479
    Points : 267
    Points
    267
    Par défaut pas de doublon
    Inutile d'épiloguer sur des doublons dans la table contrimm de l'exemple, il n'y en a pas.

    J'ai repris des tests et j'ai effectivement constaté que la syntaxe utilisant le sous select fonctionne. J'avais fait erreur dans la modification du copier-coller.

    Il n'y a en effet pas de clause FROM dans l'UPDATE d'Interbase (langref.pdf) mais l'évocation d'une table dans le sous select permet de faire une jointure avec celle citée dans l'Update.

    Milles excuses Barbibulle.

Discussions similaires

  1. [SQL Serveur] update auto jointure
    Par profy dans le forum Langage SQL
    Réponses: 4
    Dernier message: 29/05/2006, 16h10
  2. Update et jointure
    Par poca10 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 18/08/2005, 15h46
  3. Update et jointure
    Par say dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 18/07/2005, 16h29
  4. [PL/SQL] update avec jointure
    Par Fox_magic dans le forum Oracle
    Réponses: 6
    Dernier message: 09/12/2004, 12h19
  5. update et jointure
    Par damn dans le forum Langage SQL
    Réponses: 8
    Dernier message: 25/02/2004, 08h44

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