첫째, 나는이 데이터 규칙이므로 중앙 집행해야한다고 생각) ... 트리거에 대해 공부하는 것은 이번이 처음이다. 즉, 모든 응용 프로그램이 불량 데이터를 쓰지 못하게하는 DBMS에 의해 시행되는 데이터베이스 제약 조건 (또는 이에 상응하는 것)이 있어야합니다. 각 응용 프로그램의 개별 코더에 의존하여 불량 데이터를 쓰지 않도록하십시오.
둘째, AFTER
트리거가 적절하다고 생각합니다 (INSTEAD OF
트리거가 아닌).
셋째, 외래 키 및 행 수준 CHECK
제약 조건을 사용하여 강제 적용 할 수 있습니다.
제한 유형 트리거의 경우 아이디어는 일반적으로 트리거 테스트에서이 결과가 비어있는 잘못된 데이터를 반환하는 쿼리를 작성하는 것입니다.
내가 추측 할 수 있도록 테이블의 세부 정보를 많이 게시하지 않았습니다. 나는 student_number
이 학생들의 수를 의미한다고 가정합니다; 이 식별자 같은 소리 그대로 그래서 이름을 변경하고 학생들의 식별자를 가정 할 것이다 것은 student_id
입니다 :
CREATE TRIGGER student_tally_too_high ON Enrolment
AFTER INSERT, UPDATE
AS
IF EXISTS (
SELECT *
FROM Teachers AS T
INNER JOIN (
SELECT teacher_id, COUNT(*) AS students_tally
FROM Enrolment
GROUP
BY teacher_id
) AS E
ON T.teacher_id = E.teacher_id
AND E.students_tally > T.students_tally
)
BEGIN
RAISERROR ('A teachers''s student tally is too high to accept new students.', 16, 1);
ROLLBACK TRANSACTION;
RETURN
END;
: SQL 서버에서
WITH EnrolmentTallies
AS
(
SELECT teacher_id, COUNT(*) AS students_tally
FROM Enrolment
GROUP
BY teacher_id
)
SELECT *
FROM Teachers AS T
INNER JOIN EnrolmentTallies AS E
ON T.teacher_id = E.teacher_id
AND E.students_tally > T.students_tally;
는 트리거 정의는 다음과 같을 것 그러나 몇 가지 추가 고려 사항이 있습니다. 테이블에 대해 UPDATE
마다 이러한 쿼리를 실행하는 것은 매우 비효율적 일 수 있습니다. 열의 순서를 신뢰할 수 있다고 생각하면 UPDATE()
(또는 COLUMNS_UPDATED
)을 사용하거나 deleted
및 inserted
개념 테이블을 사용하여 쿼리의 범위와 실행시기를 제한해야합니다. 동시 처리 문제를 방지하려면 트랜잭션을 적절하게 직렬화해야합니다. 관련되어 있지만, 그다지 복잡하지는 않습니다.
Applied Mathematics for Database Professionals By Lex de Haan, Toon Koppelaars, 11 장 (코드 예제는 Oracle이지만 쉽게 SQL Server에 이식 할 수 있음)을 적극 권장합니다.
트리거 없이도 동일한 결과를 얻을 수 있습니다. 이 아이디어는 (teacher_id, students_tally)
에있는 수퍼 키를 등록에서 참조하도록 지정하는 것입니다. 시퀀스는 고유 한 학생 발생 순서가 유지되고 시퀀스가 최대 집계를 초과하지 않을 것이라는 테스트와 함께 유지됩니다.
CREATE TABLE Students
(
student_id INTEGER NOT NULL,
UNIQUE (student_id)
);
CREATE TABLE Teachers
(
teacher_id INTEGER NOT NULL,
students_tally INTEGER NOT NULL CHECK (students_tally > 0),
UNIQUE (teacher_id),
UNIQUE (teacher_id, students_tally)
);
CREATE TABLE Enrolment
(
teacher_id INTEGER NOT NULL UNIQUE,
students_tally INTEGER NOT NULL CHECK (students_tally > 0),
FOREIGN KEY (teacher_id, students_tally)
REFERENCES Teachers (teacher_id, students_tally)
ON DELETE CASCADE
ON UPDATE CASCADE,
student_id INTEGER NOT NULL UNIQUE
REFERENCES Students (student_id),
student_teacher_sequence INTEGER NOT NULL
CHECK (student_teacher_sequence BETWEEN 1 AND students_tally)
UNIQUE (teacher_id, student_id),
UNIQUE (teacher_id, student_id, student_teacher_sequence)
);
그런 다음 프록/기능 업데이트에 대한 순서를 유지하기 위해 저장된 일부 'help'를 추가
는 여기에 몇 가지 베어 뼈 SQL의 DDL입니다.
트리거는 데이터베이스와 관련된 경향이 있으므로 관심있는 데이터베이스를 추가해야합니다. –
StackOverflow에 오신 것을 환영합니다. 코드, XML 또는 데이터 샘플을 게시하는 경우 ** 텍스트 편집기에서 해당 행을 강조 표시하고 편집기 툴바에서 "코드 샘플"버튼 ('{})을 클릭하십시오. 구문 강조! 지저분한' 'orgies와'
' 태그는 필요하지 않습니다. –
이것은 비즈니스 규칙으로, 데이터베이스의 트리거 또는 제약 조건이 아닌 응용 프로그램 소프트웨어에서 구현할 것으로 예상됩니다. 데이터베이스 제약 조건 및 트리거는 일반적으로 참조 무결성을 적용합니다 (즉, 내부적으로 데이터를 일관되게 유지합니다). 클래스가 25를 넘지 않도록하는 것은 아마도 백스톱 일지 모르지만 앱은 실제로 처음부터 시도를 중지해야합니다. –