Est-il possible d'utiliser des jointures dans les instructions de mise à jour pour DB2?
Google m'a vraiment laissé tomber sur celui-ci
C’est à peu près ce que j’essaie d’atteindre (... sauf évidemment que je travaille ...)
update file1 inner join file2
on substr(file1.firstfield,10,20) = substr(file2.anotherfield,1,10)
set file1.firstfield = ( 'BIT OF TEXT' concat file2.something )
where file1.firstfield like 'BLAH%'
À votre santé
Vous ne dites pas quelle plate-forme vous ciblez. Faire référence à des tables en tant que fichiers, cependant, m'amène à penser que vous n'exécutez pas DB2 sous Linux, UNIX ou Windows (LUW).
Toutefois, si vous êtes sous DB2 LUW, reportez-vous à la déclaration MERGE :
Pour votre exemple d'instruction, ceci serait écrit comme suit:
merge into file1 a
using (select anotherfield, something from file2) b
on substr(a.firstfield,10,20) = substr(b.anotherfield,1,10)
when matched and a.firstfield like 'BLAH%'
then update set a.firstfield = 'BIT OF TEXT' || b.something;
Remarque: pour DB2, le troisième argument de la fonction SUBSTR est le nombre d'octets à renvoyer, pas la position finale. Par conséquent, SUBSTR (a.firstfield, 10,20) renvoie CHAR (20). Cependant, SUBSTR (b.anotherfield, 1,10) renvoie CHAR (10). Je ne sais pas si cela a été fait exprès, mais cela peut affecter votre comparaison.
Les jointures dans les instructions update
sont non standard et ne sont pas prises en charge par tous les fournisseurs. Ce que vous essayez de faire peut être accompli avec une sous-sélection:
update
file1
set
firstfield = (select 'stuff' concat something from file2 where substr(file1.field1, 10, 20) = substr(file2.xxx,1,10) )
where
file1.foo like 'BLAH%'
Essayez ceci et dites-moi les résultats:
UPDATE File1 AS B
SET b.campo1 = (SELECT DISTINCT A.campo1
FROM File2 A
INNER JOIN File1
ON A.campo2 = File1.campo2
AND A.campo2 = B.campo2)
Voici un bon exemple de quelque chose que je viens de faire:
update cac c
set ga_meth_id = (
select cim.ga_meth_id
from cci ci, ccim cim
where ci.cus_id_key_n = cim.cus_id_key_n
and ci.cus_set_c = cim.cus_set_c
and ci.cus_set_c = c.cus_set_c
and ci.cps_key_n = c.cps_key_n
)
where exists (
select 1
from cci ci2, ccim cim2
where ci2.cus_id_key_n = cim2.cus_id_key_n
and ci2.cus_set_c = cim2.cus_set_c
and ci2.cus_set_c = c.cus_set_c
and ci2.cps_key_n = c.cps_key_n
)
Mise à jour de la réponse https://stackoverflow.com/a/4184237/565525 :
si vous voulez plusieurs colonnes, cela peut être réalisé comme ceci:
update file1
set
(firstfield, secondfield) = (
select 'stuff' concat 'something from file2',
'some secondfield value'
from file2
where substr(file1.field1, 10, 20) = substr(file2.xxx,1,10) )
where
file1.foo like 'BLAH%'
Source: http://www.dbforums.com/db2/1615011-sql-update-using-join-subquery.html#post6257307
Juste pour mettre à jour uniquement les lignes qui correspondent aux conditions et éviter de mettre à jour les valeurs NULL dans les autres lignes:
update table_one set field_1 = 'ACTIVE' where exists
(select 1 from table_two where table_one.customer = table_two.customer);
Cela fonctionne dans un DB2/AIX64 9.7.8
La documentation de référence de l'instruction UPDATE sur DB2 LUW 9.7 donne l'exemple suivant:
UPDATE (SELECT EMPNO, SALARY, COMM,
AVG(SALARY) OVER (PARTITION BY WORKDEPT),
AVG(COMM) OVER (PARTITION BY WORKDEPT)
FROM EMPLOYEE E) AS E(EMPNO, SALARY, COMM, AVGSAL, AVGCOMM)
SET (SALARY, COMM) = (AVGSAL, AVGCOMM)
WHERE EMPNO = '000120'
Les parenthèses après UPDATE peuvent contenir une sélection complète, ce qui signifie que toute instruction SELECT valide peut y aller.
Sur cette base, je suggérerais ce qui suit:
UPDATE (
SELECT
f1.firstfield,
f2.anotherfield,
f2.something
FROM file1 f1
WHERE f1.firstfield like 'BLAH%'
INNER JOIN file2 f2
ON substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
)
AS my_files(firstfield, anotherfield, something)
SET
firstfield = ( 'BIT OF TEXT' || something )
Edit: Ian a raison. Mon premier instinct a été d'essayer à la place les sous-élus:
UPDATE file1 f1
SET f1.firstfield = ( 'BIT OF TEXT' || (
SELECT f2.something
FROM file2 f2
WHERE substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
))
WHERE f1.firstfield LIKE 'BLAH%'
AND substr(f1.firstfield,10,20) IN (
SELECT substr(f2.anotherfield,1,10)
FROM file2 f2
)
Mais je ne suis pas sûr si la concaténation fonctionnerait. Cela suppose également qu'il existe une correspondance 1: 1 entre les sous-chaînes. Si plusieurs lignes correspondent, cela ne fonctionnera pas.
pour vous demander
update file1 f1
set file1.firstfield=
(
select 'BIT OF TEXT' || f2.something
from file2 f2
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
)
where exists
(
select * from file2 f2
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
)
and f1.firstfield like 'BLAH%'
si rejoindre donne plusieurs résultats vous pouvez forcer la mise à jour comme ceci
update file1 f1
set file1.firstfield=
(
select 'BIT OF TEXT' || f2.something
from file2 f2
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
fetch first rows only
)
where exists
(
select * from file2 f2
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
)
and f1.firstfield like 'BLAH%'
méthode de template
update table1 f1
set (f1.field1, f1.field2, f1.field3, f1.field4)=
(
select f2.field1, f2.field2, f2.field3, 'CONSTVALUE'
from table2 f2
where (f1.key1, f1.key2)=(f2.key1, f2.key2)
)
where exists
(
select * from table2 f2
where (f1.key1, f1.key2)=(f2.key1, f2.key2)
)