DELETE lignes dont la clé est dans une table et absente d'une autre
Bonjour,
Je travaille actuellement sur 2 tables dans la configuration suivante
TABLE1
CODE1 PIC 9(005) (clé primaire)
TS1 PIC X(026) (clé primaire)
Données ...
TABLE2
CODE1 PIC 9(005) (clé primaire)
TS1 PIC X(026) (clé primaire)
CPT1 PIC 9(003) (clé primaire)
Données ...
Normalement, les lignes dans TABLE2 doivent avoir leur équivalent dans TABLE1 avec le même CODE1 et le même TS1. Mais, chez mon client, il n'y a pas de contrainte d'intégrité référentielle. Du coup on trouve des lignes présentes dans TABLE2 et pas dans TABLE1 ce qui fait planter des programmes.
Je dois donc développer un programme qui supprime les lignes présentes dans TABLE2 sans équivalent dans TABLE1 mais j'ai des contraintes à respecter au niveau des requêtes DB2 :
- Pas de requête imbriquée ou sous-requête
- Pas de FETCH pour modification
J'ai donc essayé ça :
DELETE
FROM TEST.TABLE2 B
LEFT OUTER JOIN TEST.TABLE1 A
ON (A.CODE1 = B.CODE1
AND A.TS1 = B.TS1)
WHERE A.CODE1 IS NULL
;
Mais SPUFI n'a pas aimé :
SQLCODE = -199, ERROR: ILLEGAL USE OF KEYWORD LEFT. TOKEN INCLUDE
<END-OF-STATEMENT> QUERYNO WHERE SKIP WITH SET WAS EXPECTED
SQLSTATE = 42601 SQLSTATE RETURN CODE
SQLERRP = DSNHPARS SQL PROCEDURE DETECTING ERROR
SQLERRD = 2 0 0 -1 151 506 SQL DIAGNOSTIC INFORMATION
SQLERRD = X'00000002' X'00000000' X'00000000' X'FFFFFFFF'
X'00000097' X'000001FA' SQL DIAGNOSTIC INFORMATION
Alors qu'il accepte très bien :
SELECT *
FROM TEST.TABLE2 B
LEFT OUTER JOIN TEST.TABLE1 A
ON (A.CODE1 = B.CODE1
AND A.TS1 = B.TS1)
WHERE A.CODE1 IS NULL
;
Cela me retourne très bien les lignes incriminées.
Si j'avais la possibilité de faire du DELETE sur des lignes fetchées, j'aurais déjà la solution, mais c'est interdit.
Quelqu'un aurait-il une solution pour réaliser cela sans requête imbriquée et sans DELETE sur un FETCH ?
Merci d'avance ! :)
D'amour mourir me font, belle Marquise, vos beaux yeux
Bonjour,
J’espère que, depuis le temps, Samuel a réglé son problème...
Citation:
Envoyé par escartefigue
faire un where exists avec un select * est aberrant
Ça peut paraître aberrant, mais ça n’a aucune incidence. En effet qu’on code :
Code:
1 2
| WHERE NOT EXISTS
(SELECT 1 FROM SUBQ WHERE...) ; |
Ou bien :
Code:
1 2
| WHERE NOT EXISTS
(SELECT * FROM SUBQ WHERE...) ; |
Depuis sa naissance, DB2 considère comme équivalents * ou 1 ou 2 ou ' D'amour mourir me font, belle Marquise, vos beaux yeux', dans le cas du prédicat EXISTS.
Je vous renvoie à ce qu'a écrit C. J. Date dans A Guide to DB2 en 1984 :
« Incidentally, the parenthesized subquery in an EXISTS expression does not necessarily have to involve the “SELECT *” form of SELECT; it may for example, be of the form “SELECT field-name FROM ...”. »
La doc officielle de DB2 confirme. Extrait de DB2 10 for z/OS, SQL Reference, SC19-2983 :
http://www.fsmwarden.com/developpez_...20truc...).png