PR0305 — Manipulació de dades amb Docker
Informació de la pràctica
| Camp | Valor |
|---|---|
| Codi | PR0305 |
| mòdul | M0372 — Gestió de Bases de Dades |
| RA | RA5 — DML: Manipulació de dades |
| Durada estimada | 4 hores |
| Modalitat | Individual |
| Lliurament | Fitxers SQL + informe PDF a Moodle |
| Qualificació | 10 punts (rúbrica adjunta) |
Objectius
- Poblar la BD de pràctiques amb dades coherents usant INSERT de forma massiva.
- Aplicar UPDATE amb condicions de filtratge correctes.
- Aplicar DELETE respectant la integritat referencial.
- Gestionar operacions crítiques usant transaccions explícites.
- Demostrar el comportament del ROLLBACK i dels SAVEPOINTs.
Apartat 1 — Carrega inicial de dades (3 punts)
1.1 Carrega de dades de referència
Creeu un fitxer inserts_dades_referencia.sql amb les dades bàsiques de la vostra BD (les que no canvien habitualment: categories, tipus, catàleg de productes o instal·lacions, etc.). Inseriu:
- Mínim 10 files per a cada "taula mestra".
- Useu INSERT multi-fila (una sola instruccio per a totes les files).
- Les dades han de ser coherents i realistes (no "test1", "test2", etc.).
1.2 Carrega de dades transaccionals
Creeu un fitxer inserts_dades_transaccionals.sql amb:
- Mínim 20 usuaris amb dades realistes.
- Mínim 50 reserves (distribuïdes en el temps, en diversos estats).
- Mínim 5 pagaments completats.
Per generar moltes files, podeu usar la funció generate_series de PostgreSQL:
-- Exemple: generar 20 usuaris de prova
INSERT INTO usuaris (nom, cognoms, email, dni, data_registre)
SELECT
'Usuari_' || i,
'Cognom_' || i,
'usuari' || i || '@example.com',
LPAD(i::TEXT, 8, '0') || 'Z',
CURRENT_DATE - (i || ' days')::INTERVAL
FROM generate_series(1, 20) AS i;
Apartat 2 — Actualitzacions (3 punts)
Creeu un fitxer updates.sql amb les seguents operacions:
-
Pujada de preus: Augmenteu el preu de les instal·lacions de tipus "padel" un 8%. Verificeu antes i després amb SELECT.
-
Canvi d'estat: Marqueu com a "cancel·lades" totes les reserves de l'estat "pendent" que són de fa més de 30 dies.
-
Actualització massiva: Un client ha canviat el seu email. Actualitzeu-lo per a l'usuari amb DNI 'XXXXXXXX'. Assegureu-vos que el canvi es reflecteix correctament.
-
Correcció d'errors: Una de les instal·lacions s'ha registrat per error com "inactiva" quan hauria d'estar "activa". Corregiu-ho amb un UPDATE.
-
Actualització condicional: Per a totes les reserves de l'any anterior que estan en estat "confirmada", afegiu un 5% al preu (si teniu un camp de preu calculat o a la taula de pagaments).
Per a cada UPDATE, incloeu: - El SELECT previ que mostra les files afectades. - L'UPDATE pròpiament dit. - El SELECT posterior que verifica el canvi.
Apartat 3 — Eliminació de dades (2 punts)
Creeu un fitxer deletes.sql:
-
Eliminar reserves antigues: Elimineu les reserves en estat "cancel·lada" de fa més de 6 mesos. Verifiqueu l'ordre correcte d'eliminació respectant les FK.
-
Eliminar usuari inactiu: Elimineu un usuari que no te cap reserva associada. Intenteu eliminar-ne un que SÍ te reserves i documenteu el missatge d'error.
-
Usar transacció per a eliminació segura: Englobeu una sèrie d'eliminació en una transacció. Feu ROLLBACK després de veure els resultats intermedis, i després COMMIT.
Apartat 4 — Transaccions (2 punts)
Creeu un fitxer transaccions.sql amb els seguents escenaris:
Escenari 1: Reserva completa
Implementeu una transacció que crei una nova reserva de forma atòmica:
BEGIN;
-- 1. Crear la reserva
INSERT INTO reserves (id_usuari, id_instal·lacio, data_reserva, hora_inici, hora_fi)
VALUES (1, 2, CURRENT_DATE + 7, '10:00', '11:00');
-- 2. Crear el pagament associat
INSERT INTO pagaments (id_reserva, import, metode, estat)
VALUES (LASTVAL(), 15.00, 'targeta', 'pendent');
-- 3. Verificar que tot és correcte
SELECT r.id_reserva, u.nom, i.nom AS instal·lacio, p.import
FROM reserves r
JOIN usuaris u ON r.id_usuari = u.id_usuari
JOIN instal·lacions i ON r.id_instal·lacio = i.id_instal·lacio
JOIN pagaments p ON p.id_reserva = r.id_reserva
WHERE r.id_reserva = LASTVAL();
COMMIT;
Escenari 2: ROLLBACK per error
Demostreu que el ROLLBACK funciona correctament:
BEGIN;
-- Operació 1: OK
UPDATE usuaris SET punts_fidelitat = punts_fidelitat + 10 WHERE id_usuari = 1;
-- Veure l'estat intermedi
SELECT id_usuari, punts_fidelitat FROM usuaris WHERE id_usuari = 1;
-- Simular un error
-- Intentar inserir a una taula inexistent o violar una restricció
INSERT INTO taula_que_no_existeix VALUES (1);
-- El SGBD hauria de forçar el ROLLBACK automàticament (PostgreSQL)
-- O podeu fer-lo explícitament:
ROLLBACK;
-- Verificar que els punts NO han canviat
SELECT id_usuari, punts_fidelitat FROM usuaris WHERE id_usuari = 1;
Escenari 3: SAVEPOINT
BEGIN;
SAVEPOINT inici;
-- Operació 1
INSERT INTO reserves (...) VALUES (...);
SAVEPOINT despres_reserva;
-- Operació 2 que potser falla
INSERT INTO pagaments (...) VALUES (...);
-- Si pagament falla, tornar només al punt de la reserva
ROLLBACK TO SAVEPOINT despres_reserva;
-- Intentar el pagament de nou amb dades corregides
INSERT INTO pagaments (...) VALUES (...);
COMMIT;
Entrega
-
inserts_dades_referencia.sql -
inserts_dades_transaccionals.sql -
updates.sql(amb SELECT de verificació abans i després) -
deletes.sql(amb SELECT de verificació i gestió d'errors FK) -
transaccions.sql(amb els 3 escenaris) - Informe PDF amb captures de pantalla dels resultats clau i respostes de reflexió.