Azure-Sql-Database

檢查約束年齡 18<

  • May 28, 2020

您好,我需要創建一個約束,在聽某些歌曲之前檢查使用者是 18<,但我知道如何……我試過這個:

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()) &lt; 18) 
      AND REFmusic = ( select IDmusic FROM Catalogue Where censure = 'YES') )

但是我收到了這些消息:Msg 1046, Level 15, State 1, Line 244 在這種情況下不允許子查詢。只允許標量表達式。消息 4104,級別 16,狀態 1,行 255 無法綁定多部分標識符“Catalogue.annee”。

你的約束顯然有兩個問題:

  1. Msg 1046, Level 15, State 1, Line 244 子查詢在此上下文中是不允許的。只允許標量表達式。

這意味著您不能在檢查約束中使用子查詢,您只能逐行驗證此類約束。有效檢查約束的範例是:

CHECK ( x BETWEEN 1 AND 3 )
CHECK ( x &gt; y )

我認為根據 SQL 標准允許子查詢,但很少有供應商允許它。顯然 SQL-server 不在其中。

所以這個問題的罪魁禍首是:

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

讓我們刪除該部分並嘗試:

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

我的猜測是這也是不允許的,因為 GETDATE() 不是確定性的,所以一行可能在插入期間有效,但稍後無效。永遠不允許約束評估為 False。在修改行期間,可以驗證約束,但在您的情況下,約束的真值可以在不進行任何修改的情況下更改。當約束突然評估為 False 時會採取什麼行動?沒有可以回滾的事務,沒有可以通知的使用者。

作為旁注,我不明白 Utilisateurs.Date_naissance 指的是什麼?

  1. 消息 4104,級別 16,狀態 1,行 255 無法綁定多部分標識符“Catalogue.annee”。

這個錯誤我不明白。我無法在約束中的任何位置找到 annee。

我假設歌曲的選擇被寫入某個表( Historique_ecoute )。您可以做的是創建一個驗證條件的觸發器

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

我不知道確切的語法,但你應該明白。我確實從CREATE TRIGGER複製了觸發器的東西

引用自:https://dba.stackexchange.com/questions/268032