在 DB2 中使用触发器使 table 只读

Using a trigger to make a table read-only in DB2

我需要在 DB2 中将 table 设为只读。

尽管一种选择是撤销插入、更新和删除权限,但我决定不尝试这个,因为它仍然允许 DBA 更改 table 中的数据。如果可能的话,我还想显示一个清晰的错误消息。

因此,我想探索 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

我做错了什么?

您可以使用 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.

的错误

一个触发器可以涵盖所有三种情况。例如

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 可以删除触发器,更改 table 并再次添加触发器..

如果您担心 DBA 能够修改您的数据,那么创建触发器并不能解决您的问题,因为 DBA 也可以删除触发器 (h/t @p-vernon)。

您应该对 table 实施适当的权限,如果您不信任 DBA,请实施职责分离 - 即让 DBA 以外的其他人管理权限("Security Administrator")。