触发器是Oracle数据库中特殊的存储过程,当特定事件(如INSERT、UPDATE、DELETE或DDL操作)发生时自动执行。在Linux环境下,Oracle触发器的使用逻辑与其他操作系统一致,但需注意跨平台兼容性(避免使用特定于Windows的功能)。
触发器主要分为两类:
FOR EACH ROW
子句,对受影响的每一行执行一次,适用于行级数据处理(如验证单行数据合法性)。WHEN
子句添加触发条件,仅当条件满足时触发(如仅当更新salary
列时触发验证)。CREATE TRIGGER
权限(若在他人模式下创建,需CREATE ANY TRIGGER
);OR REPLACE
可修改现有触发器(无需先删除),避免重复创建错误;COMMIT
/ROLLBACK
)或大量数据处理,防止影响数据库性能。-- 在employees表插入前验证salary不为负
CREATE OR REPLACE TRIGGER check_salary_insert
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
IF :NEW.salary < 0 THEN
RAISE_APPLICATION_ERROR(-20001, 'Salary cannot be negative');
END IF;
END;
/
-- 当employees表插入新员工时,自动插入到departments表(若部门不存在)
CREATE OR REPLACE TRIGGER sync_department
AFTER INSERT ON employees
FOR EACH ROW
DECLARE
v_dept_count NUMBER;
BEGIN
SELECT COUNT(*) INTO v_dept_count
FROM departments
WHERE department_id = :NEW.department_id;
IF v_dept_count = 0 THEN
INSERT INTO departments(department_id, department_name)
VALUES (:NEW.department_id, 'New Department');
END IF;
END;
/
-- 记录employees表的修改日志(谁、何时、修改了什么)
CREATE TABLE emp_audit (
audit_id NUMBER GENERATED ALWAYS AS IDENTITY,
emp_id NUMBER,
changed_by VARCHAR2(30),
change_time TIMESTAMP,
operation VARCHAR2(10)
);
CREATE OR REPLACE TRIGGER log_emp_changes
AFTER INSERT OR UPDATE OR DELETE ON employees
BEGIN
IF INSERTING THEN
INSERT INTO emp_audit(emp_id, changed_by, change_time, operation)
VALUES (:NEW.employee_id, USER, SYSTIMESTAMP, 'INSERT');
ELSIF UPDATING THEN
INSERT INTO emp_audit(emp_id, changed_by, change_time, operation)
VALUES (:NEW.employee_id, USER, SYSTIMESTAMP, 'UPDATE');
ELSIF DELETING THEN
INSERT INTO emp_audit(emp_id, changed_by, change_time, operation)
VALUES (:OLD.employee_id, USER, SYSTIMESTAMP, 'DELETE');
END IF;
END;
/
ALTER TRIGGER check_salary_insert DISABLE;
ALTER TRIGGER check_salary_insert ENABLE;
USER_TRIGGERS
视图查询:SELECT trigger_name, status FROM user_triggers WHERE trigger_name = 'CHECK_SALARY_INSERT';
使用DROP TRIGGER
语句彻底删除触发器:
DROP TRIGGER check_salary_insert;
SELECT text FROM user_source WHERE name = 'CHECK_SALARY_INSERT' ORDER BY line;
SELECT ANY DICTIONARY
权限):SELECT trigger_name, table_name, triggering_event, status
FROM all_triggers
WHERE owner = 'YOUR_SCHEMA';
DBMS_OUTPUT.PUT_LINE
输出调试信息(需开启SERVEROUTPUT
):CREATE OR REPLACE TRIGGER debug_trigger
BEFORE INSERT ON employees
BEGIN
DBMS_OUTPUT.PUT_LINE('Inserting into employees: ' || :NEW.employee_id);
END;
/
-- 执行前开启输出
SET SERVEROUTPUT ON;
INSERT INTO employees(employee_id, name, salary) VALUES (101, 'John Doe', 5000);
SHOW ERRORS
命令:SHOW ERRORS TRIGGER check_salary_insert;
FOLLOWS
/PRECEDES
子句控制执行顺序(Oracle 11g及以上版本支持)。通过以上技巧,可在Linux环境下高效使用Oracle触发器,实现数据完整性维护、业务逻辑自动化等需求,同时避免潜在的性能与稳定性问题。