UPDATE i DELETE
UPDATE
La instruccio UPDATE modifica els valors de columnes en files existents. Sempre ha d'anar acompanyada d'una clàusula WHERE (llevat que volgueu modificar totes les files, cosa que és molt poc freqüent i extremadament perillosa).
clients — ABANS
| id_client | nom | |
|---|---|---|
| 41 | Anna | anna·ex |
| 42 | Joan | vell·ex |
| 43 | Maria | maria·ex |
clients — DESPRÈS de l'UPDATE
| id_client | nom | |
|---|---|---|
| 41 | Anna | anna·ex |
| 42 | Pere | vell·ex |
| 43 | Maria | maria·ex |
Sintaxi bàsica
-- Actualitzar una columna d'una fila concreta
UPDATE clients
SET email = 'nou.email@example.com'
WHERE id_client = 42;
-- Actualitzar múltiples columnes alhora
UPDATE clients
SET
nom = 'Joan Antoni',
cognoms = 'Garcia i Puig',
telefon = '972999888',
data_modificacio = CURRENT_TIMESTAMP
WHERE dni = '12345678A';
-- Actualitzar basant-se en una expressió calculada
UPDATE productes
SET preu = preu * 1.05 -- Pujada del 5%
WHERE id_categoria = 3;
-- Actualitzar amb subconsulta
UPDATE productes
SET preu = preu * 0.90 -- 10% de descompte
WHERE id_producte IN (
SELECT id_producte FROM linies_comanda
WHERE id_comanda IN (
SELECT id_comanda FROM comandes
WHERE EXTRACT(YEAR FROM data_com) = 2024
)
);
UPDATE clients
SET email = 'nou.email@example.com'
WHERE id_client = 42;
-- Actualitzar múltiples columnes
UPDATE clients
SET
nom = 'Joan Antoni',
cognoms = 'Garcia i Puig',
telefon = '972999888',
data_modificacio = CURRENT_TIMESTAMP
WHERE dni = '12345678A';
-- Actualitzar amb expressió calculada
UPDATE productes
SET preu = preu * 1.05
WHERE id_categoria = 3;
-- Actualitzar amb subconsulta
UPDATE productes
SET preu = preu * 0.90
WHERE id_producte IN (
SELECT id_producte FROM linies_comanda
WHERE id_comanda IN (
SELECT id_comanda FROM comandes
WHERE EXTRACT(YEAR FROM data_com) = 2024
)
);
UPDATE amb JOIN
Tots els SGBD permeten actualitzar files basant-se en dades d'una altra taula:
-- Oracle no suporta UPDATE...FROM amb JOIN directament
-- S'usa una subconsulta correlacionada o IN:
UPDATE productes
SET preu = preu * 0.90
WHERE id_categoria IN (
SELECT id_categoria FROM categories WHERE nom = 'liquidacio'
);
-- O amb EXISTS (equivalent):
UPDATE productes p
SET preu = preu * 0.90
WHERE EXISTS (
SELECT 1 FROM categories c
WHERE c.id_categoria = p.id_categoria AND c.nom = 'liquidacio'
);
UPDATE sense WHERE
Un UPDATE sense clàusula WHERE modifica totes les files de la taula. En una taula de producció amb milions de registres, això pot ser catastròfic i irreversible. Sempre verifiqueu la clàusula WHERE amb un SELECT previ:
DELETE
La instruccio DELETE FROM elimina files d'una taula. Com l'UPDATE, sempre ha d'anar acompanyada d'un WHERE (llevat que vulgueu eliminar totes les files).
clients — ABANS
| id_client | nom | actiu |
|---|---|---|
| 41 | Anna | TRUE |
| 42 | Joan | FALSE |
| 43 | Maria | TRUE |
clients — DESPRÈS del DELETE
| id_client | nom | actiu |
|---|---|---|
| 41 | Anna | TRUE |
| ~~42~~ | ~~Joan~~ | ~~FALSE~~ |
| 43 | Maria | TRUE |
-- Eliminar una fila concreta
DELETE FROM clients WHERE id_client = 99;
-- Eliminar amb condició
DELETE FROM comandes
WHERE estat = 'cancel·lada'
AND data_com < CURRENT_DATE - INTERVAL '2 years';
-- Eliminar basant-se en una altra taula (USING a PostgreSQL)
DELETE FROM linies_comanda lc
USING comandes co
WHERE lc.id_comanda = co.id_comanda
AND co.estat = 'cancel·lada';
-- Eliminar i retornar les files eliminades (RETURNING)
DELETE FROM clients
WHERE actiu = FALSE
RETURNING id_client, nom, cognoms;
DELETE FROM clients WHERE id_client = 99;
DELETE FROM comandes
WHERE estat = 'cancel·lada'
AND data_com < ADD_MONTHS(SYSDATE, -24); -- fa 2 anys
-- Oracle no suporta DELETE...USING; s'usa IN o EXISTS:
DELETE FROM linies_comanda
WHERE id_comanda IN (
SELECT id_comanda FROM comandes WHERE estat = 'cancel·lada'
);
-- Eliminar i retornar les files eliminades (RETURNING INTO, en PL/SQL)
DELETE FROM clients
WHERE actiu = 0
RETURNING id_client, nom INTO :v_id, :v_nom;
Restriccions de clau forana en el DELETE
Si intenteu eliminar una fila que és referenciada per una FK d'una altra taula, el comportament depèn de l'acció referencial configurada:
RESTRICT/NO ACTION(per defecte): L'operació falla amb un error.CASCADE: S'eliminen en cascada totes les files dependents.SET NULL: Les FK de les files dependents es posen a NULL.
-- Intentar eliminar un client amb comandes associades (FK RESTRICT)
DELETE FROM clients WHERE id_client = 1;
-- ERROR: update or delete on table "clients" violates foreign key constraint
-- "fk_com_cli" on table "comandes"
-- Solució: eliminar primer les comandes (i les línies en cascada)
DELETE FROM comandes WHERE id_client = 1;
DELETE FROM clients WHERE id_client = 1;
TRUNCATE
TRUNCATE TABLE elimina totes les files d'una taula de forma molt més ràpida que DELETE FROM (sense WHERE). Útil per buidar taules de test o de càrrega temporal.
AC0372/05/02 — Miniactivitat
RA5 · CA5.3, CA5.4
Practiqueu UPDATE i DELETE de forma segura:
- Seleccioneu primer amb un SELECT els registres que voleu modificar.
- Executeu un UPDATE per augmentar el preu de les instal·lacions de tipus "piscina" un 10%.
- Marqueu com a "inactives" les reserves que son de fa més de 6 mesos.
- Elimineu les reserves cancel·lades de fa més d'un any.
- Documenteu cada operació amb el nombre de files afectades (
GET DIAGNOSTICS/ROW_COUNT()).