Questo pomeriggio stavo discutendo allegramente con
Spigolo su quanto detesto la mia banca (dove lavora come impiegato
), quando irrompe il solito
Andrea con una domanda intrigante che ha scovato su un forum.
L'utente domanda come sia possibile definire un CHECK Constraint su una colonna varchar che permetta l'inserimento di una lista di valori rispettando il case.
Andrea non venendone a capo ha pensato ad un paio di soluzioni:
• Definire una seconda tabella da mettere in relazione 1 a molti con la prima avente la lista di valori memorizzati in una colonna varchar con una collation case sensitive;
• Scrivere una user-defined function ad-hoc da utilizzare nella definizione del constraint;
Però non soddisfatto ha deciso di sentire anche un mio parere. Spulciando i Books Online nel paragrafo
COLLATE leggo:
Casting the collation of an expression.
You can use the COLLATE clause to cast a character expression to a certain collation.Quindi il comando COLLATE può essere utilizzato anche per i literal, così ho buttato giù il seguente codice:
USE tempdb;
GO
/* Voglio che i cognomi degli studenti siano solo
** BENAGLIA, MONTANARI, BIANCHI, HOTZ e che siano
** scritti in maiuscolo
*/
CREATE TABLE dbo.Students(
StudentID int NOT NULL IDENTITY PRIMARY KEY,
FirstName varchar(10) NOT NULL,
LastName varchar(10) NOT NULL,
CONSTRAINT CHK_LastName
CHECK(LastName IN(
'BENAGLIA' COLLATE Latin1_General_CS_AS
, 'MONTANARI' COLLATE Latin1_General_CS_AS
, 'BIANCHI' COLLATE Latin1_General_CS_AS
, 'HOTZ' COLLATE Latin1_General_CS_AS
)
)
);
GO
/* Queste righe verranno inserite correttamente */
INSERT dbo.Students VALUES('Lorenzo', 'BENAGLIA');
INSERT dbo.Students VALUES('Luca', 'BIANCHI');
/* Queste invece causeranno una violazione del constraint */
INSERT dbo.Students VALUES('Andrea', 'Montanari');
INSERT dbo.Students VALUES('Gianluca', 'hotz');
INSERT dbo.Students VALUES('David', 'DE GIACOMI');
/* Output:
Server: Msg 547, Level 16, State 1, Line 1
INSERT statement conflicted with COLUMN CHECK constraint 'CHK_LastName'.
The conflict occurred in database 'tempdb', table 'Students', column 'LastName'.
The statement has been terminated.
*/
/* Pulizia */
DROP TABLE dbo.Students;
Volete sapere la cosa bella? Il nostro Andrea non mi ha nemmeno menzionato nella sua risposta