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

Développement SQL Server Discussion :

Utilisation de transaction implicite ? [2012]


Sujet :

Développement SQL Server

  1. #1
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut Utilisation de transaction implicite ?
    Bonjour,
    J'ai la table T1 suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    id    code         ref
    55     1          toto
    44     2          toto
    66     8          titi
    77     9          titi
    Je dois inverser les 2 codes pour chaque ref identique, c'est-à-dire obtenir ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    id    code         ref
    55     2          toto
    44     1          toto
    66     9          titi
    77     8          titi
    Et tout ce que je possède, ce sont les ref et les codes, pas l'id pour former mes requêtes (car les updates sont générés automatiquement par un autre système)
    Dans un premier temps j'ai voulu faire comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    update T1 set code = 1 where id = (select id from T1 where ref = 'toto') and code = 2)
    update T1 set code = 2 where id = (select id from T1 where ref = 'toto') and code = 1)
    update T1 set code = 8 where id = (select id from T1 where ref = 'titi') and code = 9)
    update T1 set code = 9 where id = (select id from T1 where ref = 'titi') and code = 8)
    Cela ne fonctionne pas car une fois la ligne 1 et 3 exécutée, le select imbriqué des lignes 2 et 4 ne retourne plus une valeur unique.
    Je cherche donc un moyen d'exécuter les 4 lignes d'affilées. J'ai cru que j'avais trouvé en utilisant une transaction implicite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SET IMPLICIT_TRANSACTIONS ON
    update T1 set code = 1 where id = (select id from T1 where ref = 'toto') and code = 2)
    update T1 set code = 2 where id = (select id from T1 where ref = 'toto') and code = 1)
    update T1 set code = 8 where id = (select id from T1 where ref = 'titi') and code = 9)
    update T1 set code = 9 where id = (select id from T1 where ref = 'titi') and code = 8)
    commit
    SET IMPLICIT_TRANSACTIONS OFF
    Mais cela me donne la même erreur. Est-ce qu'il s'agit d'une mauvaise utilisation de la transaction implicite (est-ce que je devrais mettre des ";" et/ou des "go" ? et si oui, où s'il vous plaît ?) ou bien est-ce qu'il s'agit d'une mauvaise compréhension des transactions implicites qui ne pourraient de toute manière pas résoudre mon problème ? Si c'est le cas, voyez-vous un moyen pour résoudre mon problème s'il vous plaît ? Sachant que le "challenge" est que je dois rester sur 2 updates pour faire cette inversion et non pas 3.
    D'avance merci,

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    Bonjour,
    Pourquoi ne pas mettre un CASE dans la requête ?
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    update T1 set code = (case code when 1 then 2 when 2 then 1 end) where ref = 'toto' and code in (1,2)
    Ou avec un DECODE:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    update T1 set code = decode(code,1,2,1) where ref = 'toto' and code in (1,2)

    Tatayo.

  3. #3
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut
    Effectivement la solution avec le case fonctionne merci, je pensais que le case s'arrêtait au premier cas valide. Je garde donc cette solution en tête.
    Cependant, pour des raisons un peu complexes à expliquer ici, je préfèrerais garder une solution avec un update par ligne (2 updates donc par ref).
    Pourquoi est-ce que la solution avec IMPLICIT_TRANSACTIONS à ON ne fonctionne pas ?
    Il doit bien y avoir moyen que les updates ne s'exécutent qu'à la fin du script, une fois que les bons id auront été récupérés, non ? Je voudrais éviter aussi de passer par une table temporaire, ce qui est une autre solution de parvenir à mes fins mais pas via la méthode dont j'ai besoin.
    Merci pour votre retour,

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    Honnêtement je ne vois pas.
    Chaque update va modifier les lignes qui vérifient le where.
    Donc si on prend ces deux requêtes (j'ai supprimé une parenthèse qui était de trop):
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    update T1 set code = 1 where id = (select id from T1 where ref = 'toto' and code = 2)
    update T1 set code = 2 where id = (select id from T1 where ref = 'toto' and code = 1)
    On peut déjà les simplifier:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    update T1 set code = 1 where ref = 'toto' and code = 2
    update T1 set code = 2 where ref = 'toto' and code = 1
    Le premier update va donc modifier les lignes dont ref='toto' et code=2, et mettre 1 dans cette dernière colonne.
    Le deuxième update va modifier les lignes dont ref='toto' et code=1. Mais les lignes modifiées juste avant vérifient maintenant cette condition, et seront aussi mises à jour.
    Que les deux updates soient dans deux transactions successives ou dans la même transaction ne change rien ici.

    Donc je ne vois que 2 solutions: un seul update comme je l'avais indiqué (mais visiblement ça ne va pas), et une table temporaire (mais visiblement ça ne va pas non plus).

    Tatayo.

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    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 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    [QUOTE=jmclejPourquoi est-ce que la solution avec IMPLICIT_TRANSACTIONS à ON ne fonctionne pas ?[/QUOTE]
    Cela n'a absolument rien à voir. Toutes les transaction sont implicites par défaut dans SQL Server. Passer SET IMPLICIT_TRANSACTIONS à ON ne fait rien !
    Une transaction implicite c'est juste le fait que, lorsque vous lancez une commande SQL celle-ci est automatiquement précédée d'un BEGIN TRANSACTIOn et suivie de :
    • un COMMIT si aucune erreur n'a eut lieu
    • un ROLLBACK si une erreur a lieu


    Donc, lorsque vous lancez un lot de commande, il y a autant de transaction implicite que de commande SQL de type SELECT, INSERT, UPDATE et DELETE…
    Il doit bien y avoir moyen que les updates ne s'exécutent qu'à la fin du script, une fois que les bons id auront été récupérés, non ? Je voudrais éviter aussi de passer par une table temporaire, ce qui est une autre solution de parvenir à mes fins mais pas via la méthode dont j'ai besoin.
    Merci pour votre retour,

    Ceci serait possible en théorie si SQL Server permettait la déferrabilité des contraintes et que vous utilisiez des transactions explicites.


    Lisez l'article que j'ai écrit à ce sujet :
    https://www.developpez.com/telecharg...1f6b9815c17b66
    §6

    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/ * * * * *

  6. #6
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut
    Votre lien ne fonctionne pas, êtes-vous sûr de l'URL ?
    Mais tel que vous le dites dans votre message, je dois comprendre que ma demande n'est donc pas possible dans l'état actuel des choses ?

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    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 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    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/ * * * * *

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

Discussions similaires

  1. Utilisation des transactions
    Par choubak dans le forum VBA Access
    Réponses: 5
    Dernier message: 04/07/2007, 14h49
  2. Réponses: 2
    Dernier message: 27/06/2007, 00h37
  3. Utilisation des transactions
    Par mathias dans le forum Access
    Réponses: 1
    Dernier message: 19/03/2007, 18h18
  4. [DisplayTag] Utiliser les objets implicites
    Par starn2000 dans le forum Taglibs
    Réponses: 3
    Dernier message: 10/11/2006, 17h19
  5. utiliser une transaction avec le composant DBExpress
    Par vbcasimir dans le forum Bases de données
    Réponses: 1
    Dernier message: 09/06/2005, 14h10

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