使用触发器在DB2中将表设为只读

时间:2018-08-23 19:42:22

标签: db2 database-trigger

我需要在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

我在做什么错了?

3 个答案:

答案 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以外的其他人来管理权限(“安全管理员”)。