PROBLEMA [PostgreSQL]Definizione constraint

Pubblicità

indisparte

Nuovo Utente
Messaggi
45
Reazioni
3
Punteggio
26
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.
)
 
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
 
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?
 
SI, però allo stesso modo non puoi avere più di due scontrini non attivi, solo uno attivo e uno non attivo
 
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
 
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. --- i due messaggi sono stati uniti ---
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:
Pubblicità
Pubblicità
Indietro
Top