There are rare situations when you give up standard FOREIGN KEY mechanism in favor of something else. For example, we had one database with really huge table where tens of FKs where created. Those foreign keys took hundreds of megabytes of disk space. By their nature they referenced tables with records count in 10000-100000 times less than in main table. Having switched to triggers to support data integrity we reduced db file size noticeable and get some overall performance increase.
Foreign key like this:
alter table WORKER
add constraint WORKER_idDepartment_FK
foreign key (idDepartment)
references DEPARTMENT (idDepartment);
Can be emulated with two triggers:
CREATE TRIGGER aiu_worker FOR WORKER
AFTER INSERT OR UPDATE
POSITION 0
AS BEGIN
IF (NOT EXISTS(
SELECT idDepartment
FROM DEPARTMENT
WHERE idDepartment = NEW.idDepartment)) THEN
EXCEPTION my_exception 'There is no department with id=' ||
NEW.idDepartment;
END
CREATE TRIGGER ad_department FOR DEPARTMENT
AFTER DELETE
POSITION 0
AS BEGIN
IF (EXISTS (
SELECT idDepartment
FROM WORKER
WHERE idDepartment = OLD.idDepartment)) THEN
BEGIN
EXCEPTION my_exception 'Can not delete record';
END
END
You can easily adapt these triggers to implement CASCADE rules or support nullable fields.