Salve brobh,
brobh ha scritto:
Ciao a tutti,
vorrei utilizzare una check constraint per verificare che una certa data venga incrementata di 5 giorni, quindi dovrei aggiungere un valore di tipo INT a un altro di tipo DATE.
Utilizzando la seguente sintassi l'operazine non è riuscita perché non posso effettuare operazioni del genere su due valori con due datatype diversi ("date is incompatible with int"):
ALTER TABLE Workshops
ADD CONSTRAINT CK_Workshops_DataFine5GiorniDopoDataInizio
CHECK (DataFine = DataInizio + 5);
DataFine e DataInizio sono le due colonne di tipo DATE nella tabella Workshops.
Grazie in antipico.
@sspintux ti ha correttamente indicato un modo per avere una colonna "fittizia" (al di la' che possa essere serializzata) basata su un "mero calcolo", quindi una colonna calcolata che tendenzialmente potresti anche evitare di "scrivere" nella tabella ma semplicemente proiettare al momento della SELECT...
ma io non ho ben capito dalla tua premessa, se tu in effetti abbisogni di una cosa simile o se veramente devi validare una colonna reale che permetta una valorizzazione NON inferiore (o addirittura diversa) a quella che proponi come calcolo aritmetico...
Se ti basta la semplice proiezione, allora segui quanto indicato da @sspintux, se invece DEVI validare la valorizzazione della Colonna2 con quel presupposto, allora sempre a livello di DDL dovresti correttamente indicare un CHECK CONSTRAINT, non a livello di colonna, ma a livello di tabella...
di seguito un triviale esempio dove ometto la parola create e drop in quanto il parser del forum spesso non gradisce il DDL nei messaggi
SET NOCOUNT ON;
USE tempdb;
GO
..... TABLE [dbo].[TestTB] ( -- genera la tabella
Id int NOT NULL PRIMARY KEY,
Data1 date NOT NULL,
Data2 date,
Valore varchar(10) NOT NULL,
-- constraint a livello di tabella e non di colonna
CONSTRAINT chk_Data2$validityBasedOnData1
CHECK ( [Data2] IS NULL OR DATEDIFF( DAY, [Data1], [Data2] ) >= 5 )
);
GO
INSERT INTO [dbo].[TestTB]
VALUES ( 1, GETDATE(), DATEADD(DAY, 5, GETDATE()), 'OK' );
INSERT INTO [dbo].[TestTB]
VALUES ( 2, GETDATE(), DATEADD(DAY, 10, GETDATE()), 'OK' );
INSERT INTO [dbo].[TestTB]
VALUES ( 3, GETDATE(), NULL, 'OK' );
GO
INSERT INTO [dbo].[TestTB]
VALUES ( 4, GETDATE(), DATEADD(DAY, 4, GETDATE()), 'FALLISCE' );
GO
SELECT *
FROM [dbo].[TestTB];
GO
.... TABLE [dbo].[TestTB]; -- cancella la tabella
--<---------------------
Msg 547, Level 16, State 0, Line 24
The INSERT statement conflicted with the CHECK constraint "chk_Data2$validityBasedOnData1". The conflict occurred in database "tempdb", table "dbo.TestTB".
The statement has been terminated.
Id Data1 Data2 Valore
----------- ---------- ---------- ----------
1 2020-11-04 2020-11-09 OK
2 2020-11-04 2020-11-14 OK
3 2020-11-04 NULL OK
le prime 3 righe sono validabili e inseribili, mentre la 4^ viola il constraint e non puo' essere inserita...
vedi tu cosa meglio si avvicina alla tua necessita'...
ricorda pero' che i constraint, siano essi DEFAULT come anche CHECK, sono a tutti gli effetti un'altra cosa rispetto ad una colonna (sia essa anche "calcolata")... sono effettivamente delle "regole" fatte per la validazione dei dati, in modo da garantire che il dominio dei dati della colonna coinvolta non venga stravolto/inficiato/snaturato etc... ripeto, sono "regole"
salutoni romagnoli
--
Andrea