Bonjour,

Comme mon MERGE ne fonctionne pas, j'essaie par un traditionnel UPDATE...

Je dois donc mettre à jour ma table actuelle GRHUM.TYPE_POPULATION à partir d'une table de référence identique que j'ai stockée dans mon schéma PLEMENAGER.TYPE_POPULATION.

Les deux tables font 31 lignes.

La requête suivante me dit que j'ai 4 lignes à mettre à jour :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
SELECT *
FROM PLEMENAGER.TYPE_POPULATION rf
WHERE NOT EXISTS
(
  SELECT *
  FROM GRHUM.TYPE_POPULATION act
  WHERE act.C_TYPE_POPULATION = rf.C_TYPE_POPULATION
    AND act.LC_TYPE_POPULATION = rf.LC_TYPE_POPULATION
    AND act.LL_TYPE_POPULATION = rf.LL_TYPE_POPULATION
    AND (
        CASE 
            WHEN act.REF_REGLEMENTAIRE IS NULL AND rf.REF_REGLEMENTAIRE IS NULL THEN 1 
            WHEN act.REF_REGLEMENTAIRE = rf.REF_REGLEMENTAIRE THEN 1
            ELSE 0 
        END
    ) = 1
    AND act.TEM_FONCTIONNAIRE = rf.TEM_FONCTIONNAIRE
    AND act.TEM_ATOS = rf.TEM_ATOS
    AND act.TEM_ITARF = rf.TEM_ITARF
    AND act.TEM_ENS_SUP = rf.TEM_ENS_SUP
    AND act.TEM_ENSEIGNANT = rf.TEM_ENSEIGNANT
    AND act.TEM_2DEGRE = rf.TEM_2DEGRE
    AND act.TEM_HOSPITALIER = rf.TEM_HOSPITALIER
    AND act.TEM_BIBLIO = rf.TEM_BIBLIO
    AND act.TEM_CARRIERE = rf.TEM_CARRIERE
    AND TO_CHAR(act.D_CREATION) = TO_CHAR(rf.D_CREATION)
    AND TO_CHAR(act.D_MODIFICATION) = TO_CHAR(rf.D_MODIFICATION)
    AND act.TEM_1DEGRE = rf.TEM_1DEGRE
    AND act.TEM_VISIBLE = rf.TEM_VISIBLE
    AND 
    (
        CASE 
            WHEN act.D_OUVERTURE IS NULL AND rf.D_OUVERTURE IS NULL THEN 1 
            WHEN TO_CHAR(act.D_OUVERTURE) = TO_CHAR(rf.D_OUVERTURE) THEN 1
            ELSE 0 
        END
    ) = 1
    AND 
    (
        CASE 
            WHEN act.D_FERMETURE IS NULL AND rf.D_FERMETURE IS NULL THEN 1 
            WHEN TO_CHAR(act.D_FERMETURE) = TO_CHAR(rf.D_FERMETURE) THEN 1
            ELSE 0 
        END
    ) = 1
)
ORDER BY rf.C_TYPE_POPULATION
Comme l'examen de cette petite table m'a permis de découvrir que les différences portent surtout sur un détail de dates, j'ai commencé à construire la requête suivante qui met bien les lignes à jour mais que je trouve déjà bien compliquée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
UPDATE GRHUM.TYPE_POPULATION act
SET 
	act.D_CREATION = (
	SELECT D_CREATION
	FROM PLEMENAGER.TYPE_POPULATION rf
	WHERE rf.C_TYPE_POPULATION = act.C_TYPE_POPULATION
		AND act.C_TYPE_POPULATION IN ('AM', 'DF', 'MF', 'SF') 
	),
	act.D_MODIFICATION = (
	SELECT D_MODIFICATION
	FROM PLEMENAGER.TYPE_POPULATION rf
	WHERE rf.C_TYPE_POPULATION = act.C_TYPE_POPULATION
		AND act.C_TYPE_POPULATION IN ('AM', 'DF', 'MF', 'SF') 
	)
	-- idem pour chaque colonne
WHERE EXISTS (
	SELECT *
	FROM PLEMENAGER.TYPE_POPULATION rf1
	WHERE rf1.C_TYPE_POPULATION = act.C_TYPE_POPULATION
		AND rf1.C_TYPE_POPULATION IN ('AM', 'DF', 'MF', 'SF')
);
Le "-- idem pour chaque colonne" signifie que, dans l'absolu, je devrais avoir le même genre de code avec une sous-requête pour chaque colonne de la table.

Y a t-il une requête plus simple et plus générale pour faire cette sorte de mise à jour car j'aurai d'autres tables à traiter et potentiellement avec beaucoup plus de lignes donc impossible de "voir" facilement ce qu'il faut mettre à jour ? Et la quantité de lignes à mettre à jour risque aussi d'être beaucoup plus grand, ce qui complique encore les IN de la requête.

Serait-il par exemple possible de faire ce genre de truc :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
SET (col1, col2, col3) = (
    SELECT col1, col2, col3
    FROM -- ...
)