Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 05/06/2008, 09h45   #1
Membre éclairé
 
Inscription : novembre 2005
Messages : 385
Détails du profil
Informations forums :
Inscription : novembre 2005
Messages : 385
Points : 362
Points : 362
Par défaut UPDATE + WITH

Bonjour à tous,

est-il possible d'utiliser une clause with dans une requête de mise à jour :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
WITH 
  MY_VIEW AS (
    SELECT *
    FROM PERSONNES
  ),
  MY_VIEW2 AS (
    SELECT MY_KEY, COUNT(*) AS NB_PERSONNES
    FROM MY_VIEW
    GROUP BY MY_KEY
  )
 
UPDATE DUAL d
SET d.MY_FIELD = mv.NB_PERSONNES
FROM MY_VIEW2 mv
WHERE d.MY_KEY = mv.MY_KEY
ou


Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
UPDATE DUAL d
SET d.MY_FIELD = 
  (
    WITH 
      MY_VIEW AS (
        SELECT *
        FROM PERSONNES
      ),
      MY_VIEW2 AS (
        SELECT MY_KEY, COUNT(*) AS NB_PERSONNES
        FROM MY_VIEW
        GROUP BY MY_KEY
      )
 
     SELECT NB_PERSONNES
     FROM MY_VIEW2 mv
     WHERE mv.MY_KEY = d.MY_KEY
  )
erwan.bodere est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2008, 10h23   #2
Membre éclairé
 
Inscription : novembre 2005
Messages : 385
Détails du profil
Informations forums :
Inscription : novembre 2005
Messages : 385
Points : 362
Points : 362
J'ai réussi à faire une requête de mise en me passant du WITH.
erwan.bodere est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2008, 10h25   #3
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
tu pourrais la poster STP ?
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2008, 10h48   #4
Membre habitué
 
Inscription : février 2006
Messages : 139
Détails du profil
Informations personnelles :
Âge : 37
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : février 2006
Messages : 139
Points : 126
Points : 126
Bonjour,

Pour se passer du with, on peut ajouter rownum>0 dans la sous requete pour forcer son évaluation en premier.
Sinon il y a les hints PUSH_PRED ou PUSH_SUBQ qui peuvent rendre les memes services.

Cdt
kervoaz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2008, 11h54   #5
Membre éclairé
 
Inscription : novembre 2005
Messages : 385
Détails du profil
Informations forums :
Inscription : novembre 2005
Messages : 385
Points : 362
Points : 362
Citation:
Envoyé par orafrance Voir le message
tu pourrais la poster STP ?
j'ai simplement dupliqué mes requêtes dans des sous-requêtes au lieu de les centraliser au sein d'un bloc WITH. Voici ma requête, mais je pense qu'elle n'apportera rien

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 
UPDATE [MA_TABLE] m
SET m.[MON_CHAMP]  = 
  (
      SELECT 
            CASE 
                WHEN FIELD1 = '[VALEUR_TEST]' 
                  THEN decode(RANG,1,1,4)                  
                  ELSE decode(RANG,1,1,3) 
            END
      FROM (
              SELECT [KEY], m1.FIELD1, m1.FIELD2, m1.FIELD3, m1.FIELD4,
                     CASE
                        WHEN m1.CTR_ORI_COD = '[VALEUR_TEST]' 
                          THEN 
                            (RANK() OVER (PARTITION BY m1.FIELD1, m1.FIELD2, m1.FIELD3, m1.FIELD4 ORDER BY m1.[KEY] DESC))                        
                          ELSE
                            (RANK() OVER (PARTITION BY m1.FIELD1, m1.FIELD2, m1.FIELD3, m1.FIELD4 ORDER BY m1.[KEY] ASC)) 
                     END AS RANG
              FROM [MA_TABLE] m1, 
                   (                        
                      SELECT FIELD1, FIELD2, FIELD3, IELD4, count([KEY]) AS NB_KEYS
                      FROM [MA_TABLE]
                      GROUP BY FIELD1, FIELD2, FIELD3, FIELD4
                      HAVING count([KEY]) > 1
                   ) m2
              WHERE m1.FIELD1 = m2.FIELD1
                AND m1.FIELD2 = m2.FIELD2
                AND m1.FIELD3 = m2.FIELD3 
            ) md
       WHERE md.[KEY] = m.[KEY]                
  )
WHERE EXISTS (
    SELECT 1
    FROM (
            SELECT m1.[KEY] AS DOUBLON
            FROM [MA_TABLE] m1, 
                 (                        
                    SELECT FIELD1, FIELD2, FIELD3, FIELD4, count([KEY]) AS NB_KEYS
                    FROM [MA_TABLE]
                    GROUP BY FIELD1, FIELD2, FIELD3, FIELD4
                    HAVING count([KEY]) > 1
                 ) m2
            WHERE m1.FIELD1 = m2.FIELD1
              AND m1.FIELD2 = m2.FIELD2
              AND m1.FIELD3 = m2.FIELD3 
         ) 
    WHERE [KEY] = DOUBLON 
)

Par contre, j'aimerais bien savoir s'il est possible d'utiliser la clause WITH dans un update...
erwan.bodere est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2008, 12h10   #6
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
je crains que non
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2008, 13h35   #7
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 927
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 927
Points : 4 549
Points : 4 549
je crains que oui

Code :
1
2
3
4
5
6
7
8
9
10
11
SQL> CREATE TABLE t AS SELECT 1 x FROM dual
TABLE created.
SQL> UPDATE t SET x=(WITH v AS(SELECT 2 y FROM dual)SELECT * FROM v)
1 row updated.
SQL> commit
Commit complete.
SQL> SELECT * FROM t
 
         X
----------
         2
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2008, 13h54   #8
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
il est pas sur l'UPDATE mais sur le SELECT donc bien entendu ça fonctionne

Là l'idée était de se servir de ce WITH pour éviter d'avoir la même sous requête dans le SET et le WHERE
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2008, 14h09   #9
Membre éclairé
 
Inscription : novembre 2005
Messages : 385
Détails du profil
Informations forums :
Inscription : novembre 2005
Messages : 385
Points : 362
Points : 362
Merci pour vos réponses.
erwan.bodere est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h53.


 
 
 
 
Partenaires

Hébergement Web