en primer lugar, creo que esto es una regla de datos y por lo tanto se debe hacer cumplir de forma centralizada. Es decir, debe haber una restricción de base de datos (o equivalente) impuesta por el DBMS que impida que todas las aplicaciones escriban datos incorrectos (en lugar de confiar en que los codificadores individuales de cada aplicación se abstengan de escribir datos incorrectos).
En segundo lugar, creo que es apropiado un activador AFTER
(en lugar de un disparador INSTEAD OF
).
En tercer lugar, esto se puede aplicar utilizando claves foráneas y restricciones de nivel de fila CHECK
.
Para un desencadenador de tipo de restricción, la idea generalmente es escribir una consulta para devolver datos incorrectos, luego en la prueba de desencadenante, este resultado está vacío.
No ha publicado muchos detalles de sus tablas, así que lo adivinaré. Supongo que student_number
está destinado a ser un conteo de estudiantes; ya que es suena como un identificador así que voy a cambiar el nombre y asumir el identificador para los estudiantes es student_id
:
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;
En SQL Server, la definición de un disparador sería algo como esto:
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;
Sin embargo, hay algunas consideraciones adicionales. Ejecutar dicha consulta después de cada UPDATE
en la tabla puede ser muy ineficiente. Debe usar UPDATE()
(o COLUMNS_UPDATED
si cree que se puede confiar en el orden de las columnas) y/o las tablas conceptuales deleted
y inserted
para limitar el alcance de la consulta y cuándo se activa. También deberá asegurarse de que las transacciones estén debidamente serializadas para evitar problemas de concurrencia. Aunque involucrado, no es terriblemente complejo.
Recomiendo encarecidamente el libro Applied Mathematics for Database Professionals By Lex de Haan, Toon Koppelaars, capítulo 11 (los ejemplos del código son Oracle pero pueden ser fácilmente portados a SQL Server).
Es posible lograr lo mismo sin desencadenantes. La idea es hacer una superclave en (teacher_id, students_tally)
a la que se hará referencia en la Inscripción, para la cual se mantendrá una secuencia de ocurrencias únicas de estudiantes con una prueba de que la secuencia nunca excederá la cuenta máxima.
He aquí algunos desnudos huesos DDL SQL:
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)
);
A continuación, añadir un poco de 'ayuda' almacenan procsos/funciona para mantener la secuencia en la actualización.
Tendrá que agregar la base de datos que le interese, ya que los desencadenantes tienden a ser específicos de la base de datos. –
Bienvenido a StackOverflow: si publica código, XML o muestras de datos, ** por favor ** resalte esas líneas en el editor de texto y haga clic en el botón "muestras de código" ('{}') en la barra de herramientas del editor para formatear y sintaxis resaltarlo! No hay necesidad de ' ' orgías sucias y etiquetas '
', realmente .... –
Esta es una regla de negocios, que esperaba que se implementara en el software de la aplicación en lugar de como un disparador o una restricción en la base de datos. Las restricciones y desencadenantes de la base de datos generalmente imponen la integridad referencial (es decir, mantienen la coherencia interna de los datos) y, aunque posiblemente sea un respaldo para garantizar que las clases no superen los 25, la aplicación realmente debería detener el intento en primer lugar. –