PROBLEMA [PostgreSQL]Definizione constraint

indisparte

Nuovo Utente
42
3
Salve ho una tabella Scontrino(IdScontrino, totale, DataEmissione, Stato, IdOperatore) e una tabella Impiegato(CF,IdOperatore,...).
Devo definire il seguente vincolo :"Un operatore non può avere più di uno scontrino attivo(stato) contemporaneamente al giorno. Questo è il mio vincolo:
ALTER TABLE Scontrino
ADD CONSTRAINT unicitàScontrinoAttivo
CHECK (NOT EXISTS (SELECT I.CF, S.Data, COUNT(S.IdScontrino) AS Conto
FROM Scontrino as S NATURAL JOIN Impiegato
WHERE S.Stato='Attivo'
GROUP BY I.CF, S.Data
HAVING Conto>1));
L'errore datomi riguarda il fatto che non può esistere una subquery .Questo constraint ho provato ad inserirlo nella tabella Scontrino cliccando su constraint e specificando nel check tutto quello scritto sopra.
)
 

cdtux

Utente Èlite
1,718
756
CPU
I7 3770
Scheda Madre
Asrock Z77 Extreme 4
Hard Disk
Samsung 850 pro 250GB
RAM
Corsair Vengeance LP 16GB
Scheda Video
EVGA GTX670 SC
Monitor
Dell U2412M
Alimentatore
Corsair TX850M
Case
Corsair Graphite 760T
Sistema Operativo
Debian / Kali Linux / Win
A quanto ne so le CONSTRAINT CHECK non accettano subquery.
Se un operatore può avere SOLO uno scontrino attivo e uno passivo puoi utilizzare l'UNIQUE dei campi "DataEmissione", "Stato", "IdOperatore"
Altrimenti dai un'occhiata ai Partial Unique Index
 

indisparte

Nuovo Utente
42
3
A quanto ne so le CONSTRAINT CHECK non accettano subquery.
Se un operatore può avere SOLO uno scontrino attivo e uno passivo puoi utilizzare l'UNIQUE dei campi "DataEmissione", "Stato", "IdOperatore"
Altrimenti dai un'occhiata ai Partial Unique Index
Cioè nello stesso giorno ad esempio oggi 10/03 non posso avere 2 scontrini attivi contemporaneamente. Ne devo avere sempre uno attivo oppure non attivo, mai due contemporaneamente. Va bene lo stesso l'unique?
 

cdtux

Utente Èlite
1,718
756
CPU
I7 3770
Scheda Madre
Asrock Z77 Extreme 4
Hard Disk
Samsung 850 pro 250GB
RAM
Corsair Vengeance LP 16GB
Scheda Video
EVGA GTX670 SC
Monitor
Dell U2412M
Alimentatore
Corsair TX850M
Case
Corsair Graphite 760T
Sistema Operativo
Debian / Kali Linux / Win
SI, però allo stesso modo non puoi avere più di due scontrini non attivi, solo uno attivo e uno non attivo
 

cdtux

Utente Èlite
1,718
756
CPU
I7 3770
Scheda Madre
Asrock Z77 Extreme 4
Hard Disk
Samsung 850 pro 250GB
RAM
Corsair Vengeance LP 16GB
Scheda Video
EVGA GTX670 SC
Monitor
Dell U2412M
Alimentatore
Corsair TX850M
Case
Corsair Graphite 760T
Sistema Operativo
Debian / Kali Linux / Win
L'unique (nel caso di piu colonne) controlla che la combinazione delle n colonne sia unica nella tabella.
Nel tuo caso DataEmissione+Stato+idOperatore deve essere unica nella tabella.

Esempio:
Crei le due tabelle
Codice:
CREATE TABLE Scontrino(
   IdScontrino serial PRIMARY KEY,
   totale NUMERIC(12, 2),
   DataEmissione DATE NOT NULL,
   Stato VARCHAR(10) NOT NULL,
   IdOperatore INTEGER NOT NULL,
   UNIQUE (DataEmissione, Stato, IdOperatore)
);

CREATE TABLE Impiegato(
   id serial PRIMARY KEY,
   CF VARCHAR(11) NOT NULL
);
e inserisci dei valori
Codice:
INSERT INTO Impiegato (CF) VALUES ('AAAAAAAAAAA')

INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('10.99', '03/11/2020', 'terminato', 1 )
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('10.99', '03/11/2020', 'attivo', 1 )
Se provi ad inserire un altro scontrino attivo con la stessa data + id hai un errore
Codice:
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/11/2020', 'attivo', 1 )

ERROR:  duplicate key value violates unique constraint "scontrino_dataemissione_stato_idoperatore_key"
Stessa cosa se provi ad inserire un altro scontrino terminato con la stessa data + id hai un errore
Codice:
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/11/2020', 'terminato', 1 )

ERROR:  duplicate key value violates unique constraint "scontrino_dataemissione_stato_idoperatore_key"
Se invece vuoi inserire uno scontrino di un altro operatore o con data differente non ci sono problemi
Codice:
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/11/2020', 'attivo', 2 )
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/12/2020', 'attivo', 1 )
Con questo sistema puoi aggiungere per il medesimo operatore nella stessa data SOLO UNO scontrino attivo e SOLO UNO terminato.

Presta molta attenzione ai valori NULL che ti potrebbero creare problemi, quindi le colonne da rendere uniche è bene che siano tutte NOT NULL di default
 
  • Mi piace
Reactions: indisparte

indisparte

Nuovo Utente
42
3
L'unique (nel caso di piu colonne) controlla che la combinazione delle n colonne sia unica nella tabella.
Nel tuo caso DataEmissione+Stato+idOperatore deve essere unica nella tabella.

Esempio:
Crei le due tabelle
Codice:
CREATE TABLE Scontrino(
   IdScontrino serial PRIMARY KEY,
   totale NUMERIC(12, 2),
   DataEmissione DATE NOT NULL,
   Stato VARCHAR(10) NOT NULL,
   IdOperatore INTEGER NOT NULL,
   UNIQUE (DataEmissione, Stato, IdOperatore)
);

CREATE TABLE Impiegato(
   id serial PRIMARY KEY,
   CF VARCHAR(11) NOT NULL
);
e inserisci dei valori
Codice:
INSERT INTO Impiegato (CF) VALUES ('AAAAAAAAAAA')

INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('10.99', '03/11/2020', 'terminato', 1 )
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('10.99', '03/11/2020', 'attivo', 1 )
Se provi ad inserire un altro scontrino attivo con la stessa data + id hai un errore
Codice:
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/11/2020', 'attivo', 1 )

ERROR:  duplicate key value violates unique constraint "scontrino_dataemissione_stato_idoperatore_key"
Stessa cosa se provi ad inserire un altro scontrino terminato con la stessa data + id hai un errore
Codice:
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/11/2020', 'terminato', 1 )

ERROR:  duplicate key value violates unique constraint "scontrino_dataemissione_stato_idoperatore_key"
Se invece vuoi inserire uno scontrino di un altro operatore o con data differente non ci sono problemi
Codice:
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/11/2020', 'attivo', 2 )
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/12/2020', 'attivo', 1 )
Con questo sistema puoi aggiungere per il medesimo operatore nella stessa data SOLO UNO scontrino attivo e SOLO UNO terminato.

Presta molta attenzione ai valori NULL che ti potrebbero creare problemi, quindi le colonne da rendere uniche è bene che siano tutte NOT NULL di default
Grazie è stata una risposta molto utile ed esaustiva!!grazie davvero però chiedevo che ad esempio un operatore se ha uno scontrino attivo non ne può avere due contemporaneamente, ne deve finire prima uno (TERMINATO)e poi poter iniziare un altro quindi può avere molti Terminati e solo uno per volta attivo.
Post automaticamente unito:

ho aggiornato la risposta
L'unique (nel caso di piu colonne) controlla che la combinazione delle n colonne sia unica nella tabella.
Nel tuo caso DataEmissione+Stato+idOperatore deve essere unica nella tabella.

Esempio:
Crei le due tabelle
Codice:
CREATE TABLE Scontrino(
   IdScontrino serial PRIMARY KEY,
   totale NUMERIC(12, 2),
   DataEmissione DATE NOT NULL,
   Stato VARCHAR(10) NOT NULL,
   IdOperatore INTEGER NOT NULL,
   UNIQUE (DataEmissione, Stato, IdOperatore)
);

CREATE TABLE Impiegato(
   id serial PRIMARY KEY,
   CF VARCHAR(11) NOT NULL
);
e inserisci dei valori
Codice:
INSERT INTO Impiegato (CF) VALUES ('AAAAAAAAAAA')

INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('10.99', '03/11/2020', 'terminato', 1 )
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('10.99', '03/11/2020', 'attivo', 1 )
Se provi ad inserire un altro scontrino attivo con la stessa data + id hai un errore
Codice:
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/11/2020', 'attivo', 1 )

ERROR:  duplicate key value violates unique constraint "scontrino_dataemissione_stato_idoperatore_key"
Stessa cosa se provi ad inserire un altro scontrino terminato con la stessa data + id hai un errore
Codice:
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/11/2020', 'terminato', 1 )

ERROR:  duplicate key value violates unique constraint "scontrino_dataemissione_stato_idoperatore_key"
Se invece vuoi inserire uno scontrino di un altro operatore o con data differente non ci sono problemi
Codice:
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/11/2020', 'attivo', 2 )
INSERT INTO Scontrino (totale, DataEmissione, Stato, IdOperatore) VALUES ('20.99', '03/12/2020', 'attivo', 1 )
Con questo sistema puoi aggiungere per il medesimo operatore nella stessa data SOLO UNO scontrino attivo e SOLO UNO terminato.

Presta molta attenzione ai valori NULL che ti potrebbero creare problemi, quindi le colonne da rendere uniche è bene che siano tutte NOT NULL di default
 
Ultima modifica:
  • Mi piace
Reactions: cdtux

cdtux

Utente Èlite
1,718
756
CPU
I7 3770
Scheda Madre
Asrock Z77 Extreme 4
Hard Disk
Samsung 850 pro 250GB
RAM
Corsair Vengeance LP 16GB
Scheda Video
EVGA GTX670 SC
Monitor
Dell U2412M
Alimentatore
Corsair TX850M
Case
Corsair Graphite 760T
Sistema Operativo
Debian / Kali Linux / Win
Grazie è stata una risposta molto utile ed esaustiva!!grazie davvero però chiedevo che ad esempio un operatore se ha uno scontrino attivo non ne può avere due contemporaneamente, ne deve finire prima uno (TERMINATO)e poi poter iniziare un altro quindi può avere molti Terminati e solo uno per volta attivo.
Allora devi usare i Partial Unique Index
 

Entra

oppure Accedi utilizzando

Discussioni Simili

Hot del momento