Informix触发器是存储在数据库中的一组SQL语句,当特定事件(INSERT、UPDATE、DELETE)发生在指定表上时自动执行。
CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | DELETE | UPDATE [OF column_list]}
ON table_name
[REFERENCING {OLD AS old_name | NEW AS new_name}]
[FOR EACH {ROW | STATEMENT}]
[WHEN (condition)]
(triggered_action | BEGIN ... END)
CREATE TRIGGER check_salary
BEFORE INSERT ON employees
FOR EACH ROW
WHEN (NEW.salary < 0)
BEGIN
RAISE EXCEPTION -746, 0, "Salary cannot be negative";
END;
CREATE TRIGGER log_employee_changes
AFTER UPDATE ON employees
REFERENCING OLD AS old_emp NEW AS new_emp
FOR EACH ROW
BEGIN
INSERT INTO employee_audit (
emp_id,
change_date,
old_salary,
new_salary,
changed_by
)
VALUES (
old_emp.emp_id,
CURRENT,
old_emp.salary,
new_emp.salary,
USER
);
END;
CREATE TRIGGER cascade_delete_order
BEFORE DELETE ON orders
FOR EACH ROW
BEGIN
DELETE FROM order_items WHERE order_id = OLD.order_id;
END;
-- 查看特定表的触发器
SELECT trigname, event, owner FROM systriggers
WHERE tabid = (SELECT tabid FROM systables WHERE tabname = 'table_name');
-- 查看触发器定义
SELECT data FROM sysprocbody b, sysprocedures p
WHERE b.procid = p.procid AND p.procname = 'trigger_name';
Informix不支持直接修改触发器,需要先删除再重新创建:
DROP TRIGGER trigger_name;
-- 然后重新创建
Informix没有直接的禁用触发器命令,可以通过以下方式实现:
export INFORMIXCONTINUE=1
-- 在触发器定义中添加WHEN条件
CREATE TRIGGER trigger_name ...
WHEN (1=0) -- 条件永远为假
...
保持简洁:触发器逻辑应尽可能简单,复杂业务逻辑最好放在应用层
避免递归:确保触发器不会导致无限循环(如触发器A更新表B,而表B的触发器又更新表A)
性能考虑:FOR EACH ROW触发器对每行都执行,大数据量操作时可能影响性能
错误处理:使用RAISE EXCEPTION处理错误条件
文档记录:为触发器添加注释说明其用途
BEGIN
-- 触发器逻辑
ON EXCEPTION IN (-746) -- 捕获特定错误代码
-- 错误处理逻辑
END EXCEPTION;
END;
CREATE TRIGGER complex_trigger
BEFORE UPDATE ON accounts
REFERENCING OLD AS o NEW AS n
FOR EACH ROW
(
DEFINE v_balance_diff DECIMAL(10,2);
LET v_balance_diff = n.balance - o.balance;
-- 使用变量...
)
CREATE TRIGGER dynamic_sql_trigger
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
EXECUTE PROCEDURE log_activity('New order inserted', NEW.order_id);
END;
通过合理使用触发器,可以在Informix数据库中实现复杂的业务规则和数据完整性约束,同时减少应用层代码的复杂性。