Taules i restriccions
CREATE TABLE
La instrucció CREATE TABLE crea una nova taula amb les seves columnes i restriccions d'integritat.
Sintaxi bàsica
CREATE TABLE clients (
id_client INT AUTO_INCREMENT PRIMARY KEY,
dni CHAR(9) NOT NULL UNIQUE,
nom VARCHAR(100) NOT NULL,
cognoms VARCHAR(200) NOT NULL,
email VARCHAR(150) UNIQUE,
telefon VARCHAR(15),
data_alta DATE NOT NULL DEFAULT (CURRENT_DATE),
actiu TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE clients (
id_client NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
dni CHAR(9) NOT NULL UNIQUE,
nom VARCHAR2(100) NOT NULL,
cognoms VARCHAR2(200) NOT NULL,
email VARCHAR2(150) UNIQUE,
telefon VARCHAR2(15),
data_alta DATE DEFAULT SYSDATE NOT NULL,
actiu NUMBER(1) DEFAULT 1 NOT NULL CHECK (actiu IN (0,1))
);
Tipus de dades a Oracle
Oracle usa VARCHAR2 (no VARCHAR), NUMBER per a tots els enters i decimals, i no té tipus BOOLEAN natiu en SQL (s'emula amb NUMBER(1) o CHAR(1)). A partir d'Oracle 23c sí que existeix BOOLEAN natiu.
Tipus de dades principals
| Categoria | PostgreSQL | MySQL/MariaDB | SQL Server | Oracle | Descripció |
|---|---|---|---|---|---|
| Enters | SMALLINT, INTEGER, BIGINT |
SMALLINT, INT, BIGINT |
SMALLINT, INT, BIGINT |
NUMBER(p), INTEGER |
Nombres enters |
| Decimals | NUMERIC(p,s), REAL, DOUBLE PRECISION |
DECIMAL(p,s), FLOAT, DOUBLE |
DECIMAL(p,s), FLOAT, REAL |
NUMBER(p,s), FLOAT(p), BINARY_FLOAT, BINARY_DOUBLE |
Nombres amb decimals |
| Text fixe | CHAR(n) |
CHAR(n) |
CHAR(n), NCHAR(n) |
CHAR(n), NCHAR(n) |
Longitud fixa |
| Text variable | VARCHAR(n), TEXT |
VARCHAR(n), TEXT |
VARCHAR(n), NVARCHAR(n), TEXT |
VARCHAR2(n), NVARCHAR2(n), CLOB |
Longitud variable |
| Data/Hora | DATE, TIME, TIMESTAMP, TIMESTAMPTZ |
DATE, TIME, DATETIME, TIMESTAMP |
DATE, TIME, DATETIME, DATETIME2 |
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE |
Data i hora |
| Booleà | BOOLEAN |
TINYINT(1) |
BIT |
NUMBER(1) / CHAR(1) (≥23c: BOOLEAN) |
Valor vertader/fals |
| Binari gran | BYTEA |
BLOB, MEDIUMBLOB |
VARBINARY(MAX) |
BLOB, RAW(n) |
Dades binàries |
| Text gran | TEXT |
LONGTEXT |
NVARCHAR(MAX) |
CLOB, NCLOB |
Text de longitud il·limitada |
| JSON | JSON, JSONB |
JSON |
Funcions natives JSON | JSON (≥21c), CLOB |
Documents JSON |
| UUID | UUID |
CHAR(36) |
UNIQUEIDENTIFIER |
RAW(16) / VARCHAR2(36) |
Identificadors únics |
VARCHAR vs TEXT
A PostgreSQL i MySQL, TEXT emmagatzema text de longitud arbitrària. A PostgreSQL, no hi ha penalització de rendiment per usar TEXT en lloc de VARCHAR(n) (ambdós són equivalents en rendiment). A SQL Server, TEXT és un tipus antic; cal usar NVARCHAR(MAX).
Tipus de dades a Oracle
Oracle té un sistema de tipus propi que cal conèixer:
NUMBER(p,s)és l'únic tipus numèric bàsic d'Oracle: cobreix tant enters com decimals.pés la precisió total (màx. 38 dígits) isl'escala (decimals).INTEGERés un àlies deNUMBER(38).VARCHAR2(n)és el tipus de text variable natiu d'Oracle. EviteuVARCHAR(reservat per a ús futur). La mida màxima és 4.000 bytes per defecte (o 32.767 bytes ambMAX_STRING_SIZE=EXTENDED).DATEa Oracle emmagatzema data i hora (fins a segons), a diferència dels altres motors. No existeix un tipusTIMEindependent.TIMESTAMPesténDATEamb precisió de subsegons (fins a 9 dígits fraccionaris).TIMESTAMP WITH TIME ZONEafegeix informació de fus horari.CLOB/NCLOBemmagatzemen text de fins a 128 TB.BLOBfa el mateix per a dades binàries.BOOLEANnatiu existeix des d'Oracle 23c. En versions anteriors s'emula ambNUMBER(1)(0/1) oCHAR(1)('Y'/'N').RAW(n)emmagatzema dades binàries de longitud variable (fins a 2.000 bytes). Per a binaris grans cal usarBLOB.
Restriccions d'integritat (Constraints)
Les restriccions (constraints) són regles que el SGBD aplica automàticament per garantir la validesa de les dades. Si una operació violaria una restricció, el SGBD rebutja l'operació.
PRIMARY KEY
Identifica unívocament cada fila. Implica NOT NULL + UNIQUE. Cada taula pot tenir només una PRIMARY KEY.
Una PRIMARY KEY pot ser:
- Simple: un únic camp, habitualment un identificador numèric autoincrementat (
id_producte,id_client…). És l'opció preferida quan es pot afegir un camp artificial únic. - Composta: dos o més camps que, conjuntament, identifiquen unívocament cada fila. Cap dels camps per separat és únic; la unicitat la garanteix la combinació.
Quan usar una PK composta? En taules associatives (relacions N:M) on cada fila representa la intersecció de dues entitats. A linies_comanda, per exemple, una comanda pot tenir diverses línies i el valor num_linia = 1 existeix a moltes comandes. La combinació (id_comanda, num_linia) sí que és única i té significat de negoci: "la línia 1 de la comanda 42".
PK artificial vs PK natural
Davant el dubte, preferiu una PK artificial (SERIAL/IDENTITY/GENERATED AS IDENTITY). Les PK compostes fan que les FK que les referencien siguin més complexes i els JOINs més verbosos. Useu PK compostes quan la combinació de camps ja té significat propi i no voleu afegir redundància.
-- PK simple (a nivell de columna)
CREATE TABLE productes (
id_producte SERIAL PRIMARY KEY,
nom VARCHAR(200) NOT NULL
);
-- PK composta (a nivell de taula, obligatori quan hi ha més d'un camp)
CREATE TABLE linies_comanda (
id_comanda INTEGER NOT NULL,
num_linia SMALLINT NOT NULL,
id_producte INTEGER NOT NULL,
quantitat INTEGER NOT NULL CHECK (quantitat > 0),
CONSTRAINT pk_linies PRIMARY KEY (id_comanda, num_linia)
);
-- PK simple
CREATE TABLE productes (
id_producte INT AUTO_INCREMENT PRIMARY KEY,
nom VARCHAR(200) NOT NULL
);
-- PK composta
CREATE TABLE linies_comanda (
id_comanda INT NOT NULL,
num_linia SMALLINT NOT NULL,
id_producte INT NOT NULL,
quantitat INT NOT NULL CHECK (quantitat > 0),
PRIMARY KEY (id_comanda, num_linia)
) ENGINE=InnoDB;
-- PK simple
CREATE TABLE productes (
id_producte INT IDENTITY(1,1) PRIMARY KEY,
nom NVARCHAR(200) NOT NULL
);
-- PK composta
CREATE TABLE linies_comanda (
id_comanda INT NOT NULL,
num_linia SMALLINT NOT NULL,
id_producte INT NOT NULL,
quantitat INT NOT NULL CONSTRAINT chk_qtt CHECK (quantitat > 0),
CONSTRAINT pk_linies PRIMARY KEY (id_comanda, num_linia)
);
-- PK simple
CREATE TABLE productes (
id_producte NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
nom VARCHAR2(200) NOT NULL
);
-- PK composta
CREATE TABLE linies_comanda (
id_comanda NUMBER NOT NULL,
num_linia NUMBER(5) NOT NULL,
id_producte NUMBER NOT NULL,
quantitat NUMBER NOT NULL CONSTRAINT chk_qtt CHECK (quantitat > 0),
CONSTRAINT pk_linies PRIMARY KEY (id_comanda, num_linia)
);
FOREIGN KEY
Estableix una relació entre taules i garanteix la integritat referencial.
CREATE TABLE comandes (
id_comanda NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
id_client NUMBER NOT NULL,
data_com DATE DEFAULT SYSDATE NOT NULL,
total NUMBER(10,2),
CONSTRAINT fk_comandes_client
FOREIGN KEY (id_client)
REFERENCES clients(id_client)
ON DELETE NO ACTION
-- Oracle no suporta ON UPDATE CASCADE
);
Oracle i ON UPDATE CASCADE
Oracle no suporta ON UPDATE CASCADE. Les claus foranes d'Oracle accepten ON DELETE CASCADE i ON DELETE SET NULL, però no cap opció ON UPDATE. Si cal propagar canvis a la PK, cal fer-ho manualment o evitar canviar les claus primàries.
Clau forana que referencia una PK composta
Quan la taula referenciada té una PRIMARY KEY composta, la FOREIGN KEY ha d'incloure tots els camps de la PK en el mateix ordre. Els camps de la FK s'han de correspondre un a un amb els camps de la PK referenciada.
Exemple: la taula devolucions registra la devolució d'una línia concreta d'una comanda. Com que linies_comanda té la PK composta (id_comanda, num_linia), la FK ha de referenciar els dos camps alhora: no n'hi ha prou amb saber a quina comanda pertany, cal saber també quina línia concreta es retorna.
CREATE TABLE devolucions (
id_devolucio SERIAL PRIMARY KEY,
id_comanda INTEGER NOT NULL,
num_linia SMALLINT NOT NULL,
motiu VARCHAR(200),
data_devolucio DATE NOT NULL DEFAULT CURRENT_DATE,
-- FK composta: referencia els DOS camps de la PK de linies_comanda
CONSTRAINT fk_dev_linia
FOREIGN KEY (id_comanda, num_linia)
REFERENCES linies_comanda(id_comanda, num_linia)
ON DELETE RESTRICT
);
CREATE TABLE devolucions (
id_devolucio INT AUTO_INCREMENT PRIMARY KEY,
id_comanda INT NOT NULL,
num_linia SMALLINT NOT NULL,
motiu VARCHAR(200),
data_devolucio DATE NOT NULL DEFAULT (CURRENT_DATE),
CONSTRAINT fk_dev_linia
FOREIGN KEY (id_comanda, num_linia)
REFERENCES linies_comanda(id_comanda, num_linia)
ON DELETE RESTRICT
) ENGINE=InnoDB;
CREATE TABLE devolucions (
id_devolucio INT IDENTITY(1,1) PRIMARY KEY,
id_comanda INT NOT NULL,
num_linia SMALLINT NOT NULL,
motiu NVARCHAR(200),
data_devolucio DATE NOT NULL DEFAULT GETDATE(),
CONSTRAINT fk_dev_linia
FOREIGN KEY (id_comanda, num_linia)
REFERENCES linies_comanda(id_comanda, num_linia)
ON DELETE NO ACTION
);
CREATE TABLE devolucions (
id_devolucio NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
id_comanda NUMBER NOT NULL,
num_linia NUMBER(5) NOT NULL,
motiu VARCHAR2(200),
data_devolucio DATE DEFAULT SYSDATE NOT NULL,
CONSTRAINT fk_dev_linia
FOREIGN KEY (id_comanda, num_linia)
REFERENCES linies_comanda(id_comanda, num_linia)
ON DELETE NO ACTION
);
Índex sobre la FK composta
Molts motors no creen automàticament un índex sobre les columnes d'una FK. En FKs compostes és especialment important crear-lo manualment, ja que els JOINs i les comprovacions d'integritat referencial el necessiten:
UNIQUE
Garanteix que els valors d'una columna (o combinació de columnes) són únics a tota la taula. A diferència de PRIMARY KEY, una taula pot tenir múltiples restriccions UNIQUE i permeten valors NULL (en la majoria de motors, múltiples NULL es consideren no iguals).
-- En la definició de columna
email VARCHAR(150) UNIQUE,
-- Com a restricció de taula (millor per a noms explícits)
CONSTRAINT uq_clients_email UNIQUE (email),
-- UNIQUE compost
CONSTRAINT uq_pistes_franja UNIQUE (id_instal·lació, data_reserva, hora_inici)
NOT NULL
Garanteix que la columna no pot contenir valors NULL. Sense NOT NULL, el valor per defecte és NULL (accepta valors buits).
NULL no és zero ni cadena buida
NULL significa "valor desconegut o absent". NULL ≠ 0, NULL ≠ '', NULL ≠ FALSE. Les comparacions amb NULL sempre retornen NULL (no TRUE ni FALSE). Per verificar si un valor és NULL cal usar IS NULL o IS NOT NULL, mai = NULL.
CHECK
Defineix una condició que cada fila ha de satisfer. El SGBD rebutja qualsevol INSERT o UPDATE que violi la condició.
CREATE TABLE productes (
id_producte SERIAL PRIMARY KEY,
nom VARCHAR(200) NOT NULL,
preu numèric(10,2) NOT NULL CHECK (preu > 0),
estoc INTEGER NOT NULL DEFAULT 0 CHECK (estoc >= 0),
categoria VARCHAR(50) CHECK (categoria IN ('electronics', 'roba', 'alimentacio', 'llar'))
);
-- CHECK compost (a nivell de taula)
CREATE TABLE reserves (
id_reserva SERIAL PRIMARY KEY,
hora_inici TIME NOT NULL,
hora_fi TIME NOT NULL,
CONSTRAINT chk_hores CHECK (hora_fi > hora_inici)
);
CREATE TABLE productes (
id_producte NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
nom VARCHAR2(200) NOT NULL,
preu NUMBER(10,2) NOT NULL CONSTRAINT chk_preu CHECK (preu > 0),
estoc NUMBER DEFAULT 0 NOT NULL CONSTRAINT chk_estoc CHECK (estoc >= 0),
categoria VARCHAR2(50) CONSTRAINT chk_cat CHECK (categoria IN ('electronics', 'roba', 'alimentacio', 'llar'))
);
-- CHECK compost (a nivell de taula)
CREATE TABLE reserves (
id_reserva NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
hora_inici DATE NOT NULL,
hora_fi DATE NOT NULL,
CONSTRAINT chk_hores CHECK (hora_fi > hora_inici)
);
DATE a Oracle
A Oracle, DATE emmagatzema data i hora (fins a segons). No existeix un tipus TIME independent. Per a precisió de subsegons cal usar TIMESTAMP.
DEFAULT
Especifica el valor que s'assigna automàticament quan no és proporciona un valor explícit en un INSERT.
-- Valors per defecte típics
data_alta DATE DEFAULT CURRENT_DATE,
actiu BOOLEAN DEFAULT TRUE,
estat VARCHAR DEFAULT 'pendent',
data_creacio TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
comptador INTEGER DEFAULT 0
Exemple complet: Esquema d'una botiga
CREATE TABLE categories (
id_categoria SERIAL PRIMARY KEY,
nom VARCHAR(100) NOT NULL UNIQUE,
descripcio TEXT
);
CREATE TABLE productes (
id_producte SERIAL PRIMARY KEY,
id_categoria INTEGER NOT NULL,
codi_barres VARCHAR(20) UNIQUE,
nom VARCHAR(200) NOT NULL,
preu NUMERIC(10,2) NOT NULL CHECK (preu > 0),
estoc INTEGER NOT NULL DEFAULT 0 CHECK (estoc >= 0),
actiu BOOLEAN NOT NULL DEFAULT TRUE,
CONSTRAINT fk_prod_cat FOREIGN KEY (id_categoria)
REFERENCES categories(id_categoria) ON DELETE RESTRICT
);
CREATE TABLE clients (
id_client SERIAL PRIMARY KEY,
dni CHAR(9) NOT NULL UNIQUE,
nom VARCHAR(100) NOT NULL,
cognoms VARCHAR(200) NOT NULL,
email VARCHAR(150) NOT NULL UNIQUE,
data_alta DATE NOT NULL DEFAULT CURRENT_DATE
);
CREATE TABLE comandes (
id_comanda SERIAL PRIMARY KEY,
id_client INTEGER NOT NULL,
data_com TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
estat VARCHAR(20) NOT NULL DEFAULT 'pendent'
CHECK (estat IN ('pendent', 'confirmada', 'enviada', 'entregada', 'cancel·lada')),
total NUMERIC(10,2),
CONSTRAINT fk_com_cli FOREIGN KEY (id_client)
REFERENCES clients(id_client) ON DELETE RESTRICT
);
CREATE TABLE linies_comanda (
id_comanda INTEGER NOT NULL,
num_linia SMALLINT NOT NULL,
id_producte INTEGER NOT NULL,
quantitat INTEGER NOT NULL CHECK (quantitat > 0),
preu_unitari NUMERIC(10,2) NOT NULL CHECK (preu_unitari > 0),
CONSTRAINT pk_linies PRIMARY KEY (id_comanda, num_linia),
CONSTRAINT fk_lin_com FOREIGN KEY (id_comanda)
REFERENCES comandes(id_comanda) ON DELETE CASCADE,
CONSTRAINT fk_lin_pro FOREIGN KEY (id_producte)
REFERENCES productes(id_producte) ON DELETE RESTRICT
);
CREATE TABLE categories (
id_categoria INT AUTO_INCREMENT PRIMARY KEY,
nom VARCHAR(100) NOT NULL UNIQUE,
descripcio TEXT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE productes (
id_producte INT AUTO_INCREMENT PRIMARY KEY,
id_categoria INT NOT NULL,
codi_barres VARCHAR(20) UNIQUE,
nom VARCHAR(200) NOT NULL,
preu DECIMAL(10,2) NOT NULL CHECK (preu > 0),
estoc INT NOT NULL DEFAULT 0 CHECK (estoc >= 0),
actiu TINYINT(1) NOT NULL DEFAULT 1,
CONSTRAINT fk_prod_cat FOREIGN KEY (id_categoria)
REFERENCES categories(id_categoria) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE clients (
id_client INT AUTO_INCREMENT PRIMARY KEY,
dni CHAR(9) NOT NULL UNIQUE,
nom VARCHAR(100) NOT NULL,
cognoms VARCHAR(200) NOT NULL,
email VARCHAR(150) NOT NULL UNIQUE,
data_alta DATE NOT NULL DEFAULT (CURRENT_DATE)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE comandes (
id_comanda INT AUTO_INCREMENT PRIMARY KEY,
id_client INT NOT NULL,
data_com DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
estat VARCHAR(20) NOT NULL DEFAULT 'pendent',
CONSTRAINT chk_estat CHECK (estat IN ('pendent', 'confirmada', 'enviada', 'entregada', 'cancel·lada')),
total DECIMAL(10,2),
CONSTRAINT fk_com_cli FOREIGN KEY (id_client)
REFERENCES clients(id_client) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE linies_comanda (
id_comanda INT NOT NULL,
num_linia SMALLINT NOT NULL,
id_producte INT NOT NULL,
quantitat INT NOT NULL CHECK (quantitat > 0),
preu_unitari DECIMAL(10,2) NOT NULL CHECK (preu_unitari > 0),
CONSTRAINT pk_linies PRIMARY KEY (id_comanda, num_linia),
CONSTRAINT fk_lin_com FOREIGN KEY (id_comanda)
REFERENCES comandes(id_comanda) ON DELETE CASCADE,
CONSTRAINT fk_lin_pro FOREIGN KEY (id_producte)
REFERENCES productes(id_producte) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE categories (
id_categoria INT IDENTITY(1,1) PRIMARY KEY,
nom NVARCHAR(100) NOT NULL UNIQUE,
descripcio NVARCHAR(MAX)
);
CREATE TABLE productes (
id_producte INT IDENTITY(1,1) PRIMARY KEY,
id_categoria INT NOT NULL,
codi_barres NVARCHAR(20) UNIQUE,
nom NVARCHAR(200) NOT NULL,
preu DECIMAL(10,2) NOT NULL CONSTRAINT chk_preu CHECK (preu > 0),
estoc INT NOT NULL DEFAULT 0 CONSTRAINT chk_estoc CHECK (estoc >= 0),
actiu BIT NOT NULL DEFAULT 1,
CONSTRAINT fk_prod_cat FOREIGN KEY (id_categoria)
REFERENCES categories(id_categoria) ON DELETE NO ACTION
);
CREATE TABLE clients (
id_client INT IDENTITY(1,1) PRIMARY KEY,
dni CHAR(9) NOT NULL UNIQUE,
nom NVARCHAR(100) NOT NULL,
cognoms NVARCHAR(200) NOT NULL,
email NVARCHAR(150) NOT NULL UNIQUE,
data_alta DATE NOT NULL DEFAULT GETDATE()
);
CREATE TABLE comandes (
id_comanda INT IDENTITY(1,1) PRIMARY KEY,
id_client INT NOT NULL,
data_com DATETIME2 NOT NULL DEFAULT GETDATE(),
estat NVARCHAR(20) NOT NULL DEFAULT 'pendent'
CONSTRAINT chk_estat CHECK (estat IN ('pendent', 'confirmada', 'enviada', 'entregada', 'cancel·lada')),
total DECIMAL(10,2),
CONSTRAINT fk_com_cli FOREIGN KEY (id_client)
REFERENCES clients(id_client) ON DELETE NO ACTION
);
CREATE TABLE linies_comanda (
id_comanda INT NOT NULL,
num_linia SMALLINT NOT NULL,
id_producte INT NOT NULL,
quantitat INT NOT NULL CONSTRAINT chk_qtt CHECK (quantitat > 0),
preu_unitari DECIMAL(10,2) NOT NULL CONSTRAINT chk_preu_u CHECK (preu_unitari > 0),
CONSTRAINT pk_linies PRIMARY KEY (id_comanda, num_linia),
CONSTRAINT fk_lin_com FOREIGN KEY (id_comanda)
REFERENCES comandes(id_comanda) ON DELETE CASCADE,
CONSTRAINT fk_lin_pro FOREIGN KEY (id_producte)
REFERENCES productes(id_producte) ON DELETE NO ACTION
);
CREATE TABLE categories (
id_categoria NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
nom VARCHAR2(100) NOT NULL UNIQUE,
descripcio VARCHAR2(4000)
);
CREATE TABLE productes (
id_producte NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
id_categoria NUMBER NOT NULL,
codi_barres VARCHAR2(20) UNIQUE,
nom VARCHAR2(200) NOT NULL,
preu NUMBER(10,2) NOT NULL CHECK (preu > 0),
estoc NUMBER DEFAULT 0 NOT NULL CHECK (estoc >= 0),
actiu NUMBER(1) DEFAULT 1 NOT NULL CHECK (actiu IN (0,1)),
CONSTRAINT fk_prod_cat FOREIGN KEY (id_categoria)
REFERENCES categories(id_categoria) ON DELETE NO ACTION
);
CREATE TABLE clients (
id_client NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
dni CHAR(9) NOT NULL UNIQUE,
nom VARCHAR2(100) NOT NULL,
cognoms VARCHAR2(200) NOT NULL,
email VARCHAR2(150) NOT NULL UNIQUE,
data_alta DATE DEFAULT SYSDATE NOT NULL
);
CREATE TABLE comandes (
id_comanda NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
id_client NUMBER NOT NULL,
data_com TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
estat VARCHAR2(20) DEFAULT 'pendent' NOT NULL
CHECK (estat IN ('pendent', 'confirmada', 'enviada', 'entregada', 'cancel·lada')),
total NUMBER(10,2),
CONSTRAINT fk_com_cli FOREIGN KEY (id_client)
REFERENCES clients(id_client) ON DELETE NO ACTION
);
CREATE TABLE linies_comanda (
id_comanda NUMBER NOT NULL,
num_linia NUMBER(5) NOT NULL,
id_producte NUMBER NOT NULL,
quantitat NUMBER NOT NULL CHECK (quantitat > 0),
preu_unitari NUMBER(10,2) NOT NULL CHECK (preu_unitari > 0),
CONSTRAINT pk_linies PRIMARY KEY (id_comanda, num_linia),
CONSTRAINT fk_lin_com FOREIGN KEY (id_comanda)
REFERENCES comandes(id_comanda) ON DELETE CASCADE,
CONSTRAINT fk_lin_pro FOREIGN KEY (id_producte)
REFERENCES productes(id_producte) ON DELETE NO ACTION
);
AC0372/03/04 — Miniactivitat
RA3 · CA3.3, CA3.4
Implementeu el schema anterior en un contenidor PostgreSQL Docker. després:
- Intenteu inserir un producte amb preu negatiu. Que passa?
- Intenteu inserir una comanda amb un
id_clientinexistent. Que passa? - Intenteu eliminar una categoria que te productes associats. Que passa?
Documenteu els missatges d'error del SGBD i expliqueu quina restricció s'ha violat en cada cas.