Ограничение для таблицы отношений «многие ко многим» - обе связанные записи должны ссылаться на одну и ту же зависимую запись? - PullRequest
2 голосов
/ 27 мая 2019

Существует три объекта: Student, Class и Department. Отдел и студент имеют отношения один ко многим. У Отдела и Класса также есть отношения один ко многим. Ученик и класс имеют отношения многие ко многим.

create table Department 
(
    Id int primary key,
    -- ...
)

create table Student 
(
    Id int primary key, 
    DepartmentId int not null references Department(Id), 
    -- ....
)

create table Class 
(
    Id int primary key, 
    DepartmentId int not null references Department(Id), 
    ....
)

В следующей таблице приведены отношения «многие ко многим» между учеником и классом. Теперь пользователь может поместить в таблицу пару ученик / класс из разных (что не должно быть разрешено). Это способ предотвратить это помимо использования триггера?

create table StudentAndClass 
(
    StudentId int references Student(Id), 
    ClassId int references Class(Id), 
    -- ....
    primary key (StudentId, ClassId)
)

Ответы [ 2 ]

2 голосов
/ 27 мая 2019

Вы можете сделать это без триггера или специальных функций.Идея состоит в том, чтобы использовать отношения внешнего ключа.,,определив дополнительный набор ключей и добавив DepartmentId (избыточно) в таблицу соединений:

create table Students (
    StudentId int primary key, 
    DepartmentId int not null references Department(Id), 
    -- ....
    unique (DepartmentId, StudentId)
);

create table Classes (
    ClassId int primary key, 
    DepartmentId int not null references Department(Id), 
    ....
    unique (DepartmentId, ClassId)
);

create table StudentClasses (
    DepartmentId int references Department(DepartmentId),
    StudentId int, 
    ClassId int, 
    -- ....
    primary key (StudentId, ClassId),
    foreign key (DepartmentId, StudentId) references (DepartmentId, StudentId),
    foreign key (DepartmentId, ClassId) references (DepartmentId, ClassId),
);

Возможно, вы не хотите использовать избыточность, но это возможно без триггеров или специальных функций.

2 голосов
/ 27 мая 2019

Вы должны использовать CHECK CONSTRAINT

CREATE FUNCTION dbo.CheckDepartment()
RETURNS int
AS BEGIN RETURN (
SELECT count(1)
    FROM StudentAndClass sc
    JOIN Student s on sc.StudentId=s.id
    JOIN Class c on sc.ClassId=c.id
WHERE c.DepartmentId<>s.DepartmentId
) END
go

ALTER TABLE StudentAndClass ADD CONSTRAINT chkDep CHECK (dbo.CheckDepartment() = 0);

Это будет гарантировать, что отделы будут соответствовать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...