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 :

Update avec Select imbriqué (utilisation de for update nowait )


Sujet :

SQL Oracle

  1. #1
    Invité
    Invité(e)
    Par défaut Update avec Select imbriqué (utilisation de for update nowait )
    Bonjour,
    Dans le cadre d'un projet, j'ai une application écrite en .vb qui exécute des requêtes sur une DB oracle.
    De nombreuses instances de se programme tournent en parallèle.
    Nous nous somme aperçu qu'il y avait des accès concurrent sur une requête de mise à jour, ce qui fait que l'instance qui a pris la main fait freezer les autres.
    On ma conseillé d'utiliser (for update nowait), pourriez-vous me dire comment l'utiliser dans mon cas ?

    Voici une version mini de ma requête.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    UPDATE matable1 
    SET manewvaleur = '1' 
    WHERE id IN (
                          SELECT id 
                          FROM matable1
                          WHERE condition1 IS NULL AND condition2 IS NULL
                      )

    D'avance merci
    Dernière modification par Waldar ; 24/11/2014 à 14h39. Motif: Titre

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Vous pouvez déjà réécrire votre requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE matable1 
       SET manewvaleur = '1' 
     WHERE condition1 IS NULL
       AND condition2 IS NULL;

  3. #3
    Invité
    Invité(e)
    Par défaut
    Cela ne fonctionnera pas car la clause where récupère un id en fonction du select.
    je complète la requête pour que cela soit plus proche du réelle.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    UPDATE matable1 
    SET manewvaleur = '1' 
    WHERE id IN (
                          SELECT id
                          FROM (
                                       SELECT id 
                                       FROM matable1
                                       WHERE condition1 IS NULL AND condition2 IS NULL
                                   ) tmp 
                          WHERE Rownum=1
                      )

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 789
    Points
    30 789
    Par défaut
    Tu sélectionnes donc aléatoirement un Id correspondant à tes conditions...
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  5. #5
    Invité
    Invité(e)
    Par défaut
    C'est pas de l'aléatoire car il y a un order by en plus pour prendre le dernier arrivé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    UPDATE matable1 
    SET manewvaleur = '1' 
    WHERE id IN (
                          SELECT id
                          FROM (
                                       SELECT id 
                                       FROM matable1
                                       WHERE condition1 IS NULL AND condition2 IS NULL
                                       ORDER BY condition2 DESC, condition4 DESC
                                   ) tmp 
                          WHERE Rownum=1
                      )

  6. #6
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 789
    Points
    30 789
    Par défaut
    A force d'interrogations, on finira par connaître les conditions réelles d'exécution de la requête...

    Avec quelle version d'Oracle cette requête est-elle exécutée ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  7. #7
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 789
    Points
    30 789
    Par défaut
    Serait-ce cela que tu cherches à faire ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    UPDATE  matable1 
    SET     manewvaleur = '1' 
    WHERE   id  =   (   SELECT  LAST_VALUE(id) OVER (ORDER BY condition3, condition4)
                        FROM    matable1
                        WHERE   condition1 IS NULL 
                            AND condition2 IS NULL
                    )
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Il s'agit de la version 10G d'Oracle.
    Par contre si j'exécute ton exemple j'ai plusieurs résultat et non pas qu'un seul id.
    A noté que mon champ s'appel pas (id) comme dans mon exemple mais "id_instance" cela à t'il une incidence

  9. #9
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 789
    Points
    30 789
    Par défaut
    En effet, il faut préciser RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING dans la clause OVER
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  10. #10
    Invité
    Invité(e)
    Par défaut
    En effet il y a du mieux.
    Par contre j'ai du rajouter un distinct car sinon, j'avais autant de ligne que de résultat entrant dans la condition, mais par contre ils avaient tous le même id.

    Du coups comment utiliser le "for update nowait", car je cherche toujours à empêcher les accès concurrent.

  11. #11
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    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 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Vous ne pouvez pas empêcher les accès concurrents, sauf à démarrer une transaction en mode UPDATE au niveau d'isolation SERIALIZABLE. Ce sera donc bien pire pour tous les autres accès.

    FOR UPDATE NO WAIT, ne propose pas de prendre la main immédiatement pour exécuter l'ordre UPDATE, mais rend la main immédiatement si la ressource est déjà verrouillé !

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

  12. #12
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    sauf à démarrer une transaction en mode UPDATE au niveau d'isolation SERIALIZABLE.
    Je ne vois pas ce que le SERIALIZABLE change par rapport à un UPDATE en READ COMMITED.
    Citation Envoyé par SQLpro Voir le message
    FOR UPDATE NO WAIT, ne propose pas de prendre la main immédiatement pour exécuter l'ordre UPDATE, mais rend la main immédiatement si la ressource est déjà verrouillé !
    Ben c'est bien ce qu'il veut faire, enfin d'après ce que j'ai compris.

    Pour le SELECT FOR UPDATE NOWAIT, quel est le problème ?
    Il suffit d'utiliser la sous-requête avec FOR UPDATE NOWAIT, puis de faire l'update.

  13. #13
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Je ne vois pas ce que le SERIALIZABLE change par rapport à un UPDATE en READ COMMITED.
    ...
    Oups! ANSI/ISO Transaction Isolation Levels

  14. #14
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    ...FOR UPDATE NO WAIT, ne propose pas de prendre la main immédiatement pour exécuter l'ordre UPDATE, mais rend la main immédiatement si la ressource est déjà verrouillé !

    A +
    Un Select ... for update verrouille les enregistrement immédiatement si ces enregistrements ne sont pas déjà verrouillés par un autre utilisateur.

  15. #15
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    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 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Un Select ... for update verrouille les enregistrement immédiatement si ces enregistrements ne sont pas déjà verrouillés par un autre utilisateur.
    Mais ceci est le comportement naturel de n'importe quel ordre de mise à jour...

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

  16. #16
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Mais ceci est le comportement naturel de n'importe quel ordre de mise à jour...

    A +
    Bref si vous y tenez vraiment alors (n')utilisez (pas) Select ... For Update Skip Locked

Discussions similaires

  1. [Delphi6,Access] Requête update avec select imbriqué
    Par magicstar dans le forum Débuter
    Réponses: 3
    Dernier message: 30/03/2009, 19h40
  2. requete update avec select imbriqué
    Par mikees dans le forum SQL
    Réponses: 3
    Dernier message: 09/02/2009, 17h42
  3. UPDATE avec SELECT sur la même table
    Par Invité dans le forum Langage SQL
    Réponses: 7
    Dernier message: 07/12/2007, 03h39
  4. Requete Update avec Select imbriqué: etrange resultat!
    Par corentone dans le forum Langage SQL
    Réponses: 3
    Dernier message: 13/08/2007, 15h05
  5. Réponses: 3
    Dernier message: 22/12/2005, 17h47

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