我需要在DB2中将表设为只读。
尽管一个选项是撤销插入,更新和删除特权,但我还是决定不尝试使用该特权,因为它仍然允许DBA更改表中的数据。如果可能的话,我还要显示一个清晰的错误消息。
因此,我想探讨DB2触发器的选项,但是恐怕我在这方面还不是专家。当我尝试创建它时,出现错误。
在这一点上,我尝试了无数种变体,但无法使其正常工作。这是DDL:
create table employee_state (
id int primary key not null,
description varchar(40) not null
);
insert into employee_state (id, description) values (1, 'Applying');
insert into employee_state (id, description) values (2, 'Rejected');
insert into employee_state (id, description) values (3, 'Active');
insert into employee_state (id, description) values (4, 'Inactive');
create trigger employee_state_read_only
before delete on employee_state for each statement
begin
raise_error(-20001,
'Delete operation not allowed on read-only table "employee_state".');
end//
DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=raise_error;ach statement
begin
;RETURN, DRIVER=4.21.29
我在做什么错了?
答案 0 :(得分:1)
您可以在自定义消息中使用SIGNAL
SQLSTATE
。
CREATE TRIGGER EMPLOYEE_STATE_READ_ONLY
BEFORE DELETE ON EMPLOYEE_STATE FOR EACH ROW
WHEN (1=1)
BEGIN ATOMIC
SIGNAL SQLSTATE '80001' SET MESSAGE_TEXT = 'READ ONLY';
END
然后在尝试删除时会抛出类似SQL0723 - SQL trigger EMPLOYEE_STATE_READ_ONLY in GLTCUAT failed with SQLCODE -438 SQLSTATE 80001.
的错误
答案 1 :(得分:1)
单个触发器可以涵盖所有三种情况。例如
CREATE OR REPLACE TRIGGER EMPLOYEE_STATE_READ_ONLY
BEFORE INSERT OR DELETE OR UPDATE ON EMPLOYEE_STATE
FOR EACH ROW BEGIN SIGNAL SQLSTATE '80001' SET MESSAGE_TEXT = 'READ ONLY'; END
当然,DBA可以删除触发器,对表进行更改,然后再次添加触发器。
答案 2 :(得分:0)
如果您担心DBA能够修改数据,那么创建触发器将无法解决您的问题,因为DBA也可以删除触发器(h / t @ p-vernon)。
您应该在表上实现适当的权限,如果您不信任DBA,请实现职责分离-即由DBA以外的其他人来管理权限(“安全管理员”)。