Question

Hello I need to create a constraint that chekc the user is 18< before listenning to certain songs but idk how... I tried this :

ALTER TABLE Historique_ecoute
DROP CONSTRAINT IF EXISTS majorite_utilisateur
GO

ALTER TABLE Historique_ecoute
ADD CONSTRAINT majorite_utilisateur
CHECK (not (DATEDIFF(yyyy, Utilisateurs.Date_naissance, GETDATE()) < 18) 
       AND REFmusic = ( select IDmusic FROM Catalogue Where censure = 'YES') )

But I get thoses messages : Msg 1046, Level 15, State 1, Line 244 Subqueries are not allowed in this context. Only scalar expressions are allowed. Msg 4104, Level 16, State 1, Line 255 The multi-part identifier "Catalogue.annee" could not be bound.

Was it helpful?

Solution

There are apparently 2 problems with you constraint:

  1. Msg 1046, Level 15, State 1, Line 244 Subqueries are not allowed in this context. Only scalar expressions are allowed.

What this means is that you can not use a subquery inside a check constraint, you can only validate such constraint row by row. Examples of valid check constraints would be:

CHECK ( x BETWEEN 1 AND 3 )
CHECK ( x > y )

I think sub-queries are allowed according to SQL-standard, but few if any vendors allow it. Apparently SQL-server is not among those that do.

so the culprit for this problem is:

AND REFmusic = ( select IDmusic FROM Catalogue Where censure = 'YES' )

Let's remove that part and try:

ALTER TABLE Historique_ecoute ADD CONSTRAINT majorite_utilisateur
   CHECK (not (DATEDIFF(yyyy, Utilisateurs.Date_naissance, GETDATE()) < 18)

My guess is that this is not allowed either, because GETDATE() is not deterministic, so a row may be valid during insert but invalid a little bit later. A constraint is never allowed to evaluate to False. During a modification of a row, the constraints can be validated, but in your case, the truth value of the constraint can change without any modification being made. What action would be taken when the constraint all the sudden evaluates to False? There is no transaction that can be rolled backed, no user that can be notified.

As a side-note, I don't understand what Utilisateurs.Date_naissance refers to?

  1. Msg 4104, Level 16, State 1, Line 255 The multi-part identifier "Catalogue.annee" could not be bound.

This error I don't understand. I can't locate annee anywhere in the constraint.

I assume that the choice of song is written to some table ( Historique_ecoute ). What you can do is create a trigger that validates the condition

CREATE TRIGGER validate_age ON Historique_ecoute   
AFTER INSERT
AS 
    IF (DATEDIFF(yyyy, Utilisateurs.Date_naissance, GETDATE()) < 18)
         RAISERROR ('You are not allowed to ...',  
         ROLLBACK TRANSACTION;  
    END;  

I don't know the exact syntax, but you should get the idea. I did copy the trigger stuff from CREATE TRIGGER

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top