簡體   English   中英

無法將 CHECK 約束應用於 MySQL 表

[英]Unable to apply CHECK constraint to a MySQL table

我正在嘗試為學生實驗室場景構建一個小型數據庫模式。首先我創建了classes表:

CREATE TABLE classes (
    class_id INT NOT NULL,
    class_name VARCHAR(50) NOT NULL,
    PRIMARY KEY (class_id),
    UNIQUE (class_name)
);

然后我創建了labs表:

CREATE TABLE labs (
    lab_id INT NOT NULL,
    lab_name VARCHAR(50) NOT NULL,
    class_id INT NOT NULL,
    PRIMARY KEY (lab_id),
    UNIQUE (lab_name),
    FOREIGN KEY (class_id) REFERENCES classes (class_id)
);

在此之后,我創建了students表:

CREATE TABLE students (
    student_id INT AUTO_INCREMENT NOT NULL,
    student_name VARCHAR(50) NOT NULL,
    class_id INT NOT NULL,
    PRIMARY KEY (student_id),
    FOREIGN KEY (class_id) REFERENCES classes (class_id)
);

最后我創建了allotments表來為學生分配實驗室:

CREATE TABLE allotments (
    student_id INT  NOT NULL,
    lab_id INT NOT NULL,
    day_of_week CHAR(3) NOT NULL,
    PRIMARY KEY (student_id, lab_id),
    FOREIGN KEY (student_id) REFERENCES students (student_id),
    FOREIGN KEY (lab_id) REFERENCES labs (lab_id)
);

這似乎很好。 但我想在allotments表中添加一個CHECK約束,以便學生僅分配到各自班級的實驗室,如下所示:

ALTER TABLE allotments
ADD CHECK (student_id IN (SELECT student_id
                      FROM students INNER JOIN labs USING (class_id)
                      WHERE students.class_id = labs.class_id));

但是當我嘗試這個時,我收到以下錯誤消息: Error Code: 3815. An expression of a check constraint 'allotments_chk_1' contains disallowed function. 0.000 sec Error Code: 3815. An expression of a check constraint 'allotments_chk_1' contains disallowed function. 0.000 sec請幫助我解決問題。

我遵循@P.Salmon 的想法來使用觸發器,並且我找到了一種應用完整性約束的方法,這樣只有當student_idlab_id都屬於同一個 class 時,用戶才能將實驗室分配給學生。

這是要使用的觸發器:

DELIMITER $$
CREATE TRIGGER before_allotments_insert
    BEFORE INSERT
    ON allotments FOR EACH ROW
BEGIN
    DECLARE students_class_id, labs_class_id INT;
    DECLARE error_message VARCHAR(100);
    SET error_message = CONCAT('Invalid lab_id for student_id ', NEW.student_id);
    SELECT class_id INTO students_class_id
    FROM students
    WHERE student_id = NEW.student_id;
    SELECT class_id INTO labs_class_id
    FROM labs
    WHERE lab_id = NEW.lab_id;
    IF students_class_id <> labs_class_id THEN
        SIGNAL SQLSTATE '45000'
            SET MESSAGE_TEXT = error_message;
    END IF;
END $$
DELIMITER ;

當用戶嘗試為學生插入新分配並驗證條目時,此觸發器會自動調用。 如果student_idlab_id不屬於同一個 class,則會顯示一條錯誤消息,限制其條目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM