PDA

Visualizza la versione completa : [SQL] UPDATE selettiva in base a SELECT (era: update complesso)


fumuso69
23-09-2009, 10:09
Devo eseguire la seguente query:

update tabella 1
set campo 1 = (select campo 2 from tabella 1, tabella 2
where condizione di join delle due tabelle)

Qualora la select dia valore null come posso modificare la query in modo che nel set prenda il campo 1 della tabella 1 .

Grazie.

darksoullight88
23-09-2009, 10:19
che db usi?

EDIT:
leggi il regolamento e modifica il titolo della discussione altrimenti chiudono

DonFrignolo
25-09-2009, 11:19
Originariamente inviato da fumuso69
Devo eseguire la seguente query:

update tabella 1
set campo 1 = (select campo 2 from tabella 1, tabella 2
where condizione di join delle due tabelle)

Qualora la select dia valore null come posso modificare la query in modo che nel set prenda il campo 1 della tabella 1 .

Grazie.

Potresti fare cosi



update tabella 1
set campo 1 = (select
case when isnull(campo 2) then campo1
else campo2
end as campo
from tabella 1, tabella 2
where condizione di join delle due tabelle)

fumuso69
25-09-2009, 13:29
Ti riporto la query scritta in maniera esplicita

UPDATE DBCN01.TB_CN_HSTBSTCV A
SET A.HSTBSTCV_NRAPINT=
(SELECT CASE
WHEN ISNULL(B.HSTBDORM_NRAPINT)
THEN A.HSTBSTCV_NRAPINT
ELSE B.HSTBDORM_NRAPINT
END AS CAMPO
FROM DBCN01.TB_CN_HSTBDORM B
WHERE B.HSTBDORM_CCODDIP = A.HSTBSTCV_CCODDIP
AND B.HSTBDORM_CCODSRV = A.HSTBSTCV_CCODSRV
AND B.HSTBDORM_CNUMRAP = A.HSTBSTCV_CNUMRAP
AND B.HSTBDORM_CCODCAT = A.HSTBSTCV_CCODCAT
AND B.HSTBDORM_NRAPINT <>A.HSTBSTCV_NRAPINT)

------------------------------------------------------------------
eseguendola in db2 mi dà questo errore
SQL error at or before THEN
(line 6, position 1).

DonFrignolo
25-09-2009, 13:47
prova con


CASE WHEN (B.HSTBDORM_NRAPINT IS NULL)
THEN A.HSTBSTCV_NRAPINT
ELSE B.HSTBDORM_NRAPINT

perchè isnull(campo,ritorno) è una funzione
potresti fare anche


ISNULL(B.HSTBDORM_NRAPINT,A.HSTBSTCV_NRAPINT)

dovrebbe essere la stessa cosa

fumuso69
25-09-2009, 14:17
Ho corretto la query

UPDATE DBCN01.TB_CN_HSTBSTCV A
SET A.HSTBSTCV_NRAPINT=
(SELECT CASE
WHEN (B.HSTBDORM_NRAPINT IS NULL)
THEN A.HSTBSTCV_NRAPINT
ELSE B.HSTBDORM_NRAPINT
END AS CAMPO
FROM DBCN01.TB_CN_HSTBDORM B
WHERE B.HSTBDORM_CCODDIP = A.HSTBSTCV_CCODDIP
AND B.HSTBDORM_CCODSRV = A.HSTBSTCV_CCODSRV
AND B.HSTBDORM_CNUMRAP = A.HSTBSTCV_CNUMRAP
AND B.HSTBDORM_CCODCAT = A.HSTBSTCV_CCODCAT
AND B.HSTBDORM_NRAPINT <>A.HSTBSTCV_NRAPINT)

però becco questo errore

QUERY MESSAGES:
Column cannot contain a NULL value.

è come se non sentisse il when

DonFrignolo
25-09-2009, 14:27
Originariamente inviato da fumuso69
Ho corretto la query

UPDATE DBCN01.TB_CN_HSTBSTCV A
SET A.HSTBSTCV_NRAPINT=
(SELECT CASE
WHEN (B.HSTBDORM_NRAPINT IS NULL)
THEN A.HSTBSTCV_NRAPINT
ELSE B.HSTBDORM_NRAPINT
END AS CAMPO
FROM DBCN01.TB_CN_HSTBDORM B
WHERE B.HSTBDORM_CCODDIP = A.HSTBSTCV_CCODDIP
AND B.HSTBDORM_CCODSRV = A.HSTBSTCV_CCODSRV
AND B.HSTBDORM_CNUMRAP = A.HSTBSTCV_CNUMRAP
AND B.HSTBDORM_CCODCAT = A.HSTBSTCV_CCODCAT
AND B.HSTBDORM_NRAPINT <>A.HSTBSTCV_NRAPINT)

però becco questo errore

QUERY MESSAGES:
Column cannot contain a NULL value.

è come se non sentisse il when

Prova a lanciare solo la select per vedere cosa tira fuori e controllare che i dati siano quelli che ti servono, forse tira fuori qualche null che non dovrebbe esserci.
e comunque la select mi torna poco, dove è la inner con la tabella A nella select?


SELECT CASE
WHEN (B.HSTBDORM_NRAPINT IS NULL)
THEN A.HSTBSTCV_NRAPINT
ELSE B.HSTBDORM_NRAPINT
END AS CAMPO
FROM DBCN01.TB_CN_HSTBDORM B
INNER JOIN DBCN01.TB_CN_HSTBSTCV INT ON B.HSTBDORM_CCODDIP = INT.HSTBSTCV_CCODDIP
AND B.HSTBDORM_CCODSRV = INT.HSTBSTCV_CCODSRV
AND B.HSTBDORM_CNUMRAP = INT.HSTBSTCV_CNUMRAP
AND B.HSTBDORM_CCODCAT = INT.HSTBSTCV_CCODCAT
AND B.HSTBDORM_NRAPINT <>INT.HSTBSTCV_NRAPINT

non dovrebbe essere cosi?
Comunque lancia la select e controllane la correttezza prima di esegure update.

fumuso69
25-09-2009, 15:05
la select tira fuori qualche null e per questo nel caso vi sia il null il campo da updatare deve essere svorascritto da se stesso...la inner non c'è per la join fa riferimento alla tabella definita dopo l'update ... se inserisco la inner join come mi hai indicato la select estrae + valori nel senso che a parità di chiave ho 1 riga su dorm e n su stcv ...inoltre sulla stcv ci sono righe non presenti su dorm e quindi io devo modificare il canpo rapint di stcv presente su dorm

DonFrignolo
25-09-2009, 15:35
ok, ho capito. Comunque c'è qualche caso in cui entrambi i valori sono null, o qualche caso in cui la where condition non è soddisfatta per nessun valore, altrimenti la select non li tirerebbe fuori.
Puoi provare cosi:


UPDATE DBCN01.TB_CN_HSTBSTCV A
SET A.HSTBSTCV_NRAPINT= case when
((SELECT B.HSTBDORM_NRAPINT
FROM DBCN01.TB_CN_HSTBDORM B
WHERE B.HSTBDORM_CCODDIP = A.HSTBSTCV_CCODDIP
AND B.HSTBDORM_CCODSRV = A.HSTBSTCV_CCODSRV
AND B.HSTBDORM_CNUMRAP = A.HSTBSTCV_CNUMRAP
AND B.HSTBDORM_CCODCAT = A.HSTBSTCV_CCODCAT
AND B.HSTBDORM_NRAPINT <>A.HSTBSTCV_NRAPINT) is null) then

A.HSTBDORM_NRAPINT

else
(SELECT B.HSTBDORM_NRAPINT
FROM DBCN01.TB_CN_HSTBDORM B
WHERE B.HSTBDORM_CCODDIP = A.HSTBSTCV_CCODDIP
AND B.HSTBDORM_CCODSRV = A.HSTBSTCV_CCODSRV
AND B.HSTBDORM_CNUMRAP = A.HSTBSTCV_CNUMRAP
AND B.HSTBDORM_CCODCAT = A.HSTBSTCV_CCODCAT
AND B.HSTBDORM_NRAPINT <>A.HSTBSTCV_NRAPINT)
end

Loading