Oracle View 不可更新,关于 Instead Of 触发器的建议

标签 oracle plsql

在迁移系统/数据库后,我们修改了一个中央表,该表已用于与 15 个不同的系统连接。我们使用此迁移来添加和删除此表中的一些字段。

为了保持与接口(interface)系统的直接兼容性(即只需要更改数据库链接),已创建一个 View ,该 View 显示与旧表完全相同的列。但是,其中一些列只是模拟的,因此 View 包含如下结构:

(...)
CREATE OR REPLACE VIEW STAFF_DATA_COMPAT AS
SELECT
  NVL(knownas_surname,surname) as surname,
  first_name
  middle_name as mid-name
  NULL as ni,
  NULL as home_tel_no,
(...)

显然,此 View 本身不可更新

我明白,所有 DML(插入、更新、删除)语句都需要 INSTEAD OF 触发器。 我可以看到,INSTEAD OF INSERT 触发器应该非常简单(只需在适当的地方将 :NEW.field 插入到真实表中并忽略其他)。

但真正的问题是:如何编写相应的 INSTEAD OF UPDATE/DELETE 触发器?例如,我如何接管原始 DELETE 语句的“WHERE”子句?在使用这些触发器时,还有什么我应该担心的吗?有任何副作用吗?

顺便说一句。这是 Oracle 11g。

最佳答案

INSTEAD OF 触发器看起来像这样(我假设您有一个主键列 id):

SQL> CREATE OR REPLACE TRIGGER trg_staff_data_cpt_instead_upd
  2     INSTEAD OF UPDATE ON staff_data_compat
  3     FOR EACH ROW
  4  BEGIN
  5     UPDATE staff_data_compat_t
  6        SET knownas_surname = :new.surname,
  7            first_name = :new.first_name,
  8            middle_name = :new.mid_name
  9      WHERE id = :new.id
 10  END;
 11  /

Trigger created

请注意,某些列实际上可能在原始 View 中是可更新的。查询 all_updatable_columns View (在创建触发器之前)以找出:

SQL> CREATE TABLE staff_data_compat_t AS
  2  SELECT object_name knownas_surname,
  3         owner surname,
  4         object_type first_name,
  5         subobject_name middle_name
  6    FROM all_objects;

Table created

SQL> CREATE OR REPLACE VIEW staff_data_compat AS
  2  SELECT
  3    NVL(knownas_surname,surname) as surname,
  4    first_name,
  5    middle_name mid_name,
  6    NULL as ni,
  7    NULL as home_tel_no
  8  FROM staff_data_compat_t;

View 已创建

SQL> SELECT * FROM all_updatable_columns WHERE table_name = 'STAFF_DATA_COMPAT';

OWNER  TABLE_NAME         COLUMN_NAME  UPDATABLE INSERTABLE DELETABLE
------ ------------------ ------------ --------- ---------- ---------
VNZ    STAFF_DATA_COMPAT  SURNAME      NO        NO         NO
VNZ    STAFF_DATA_COMPAT  FIRST_NAME   YES       YES        YES
VNZ    STAFF_DATA_COMPAT  MID_NAME     YES       YES        YES
VNZ    STAFF_DATA_COMPAT  NI           NO        NO         NO
VNZ    STAFF_DATA_COMPAT  HOME_TEL_NO  NO        NO         NO

如果您只需要插入/更新这些列,则不需要 INSTEAD OF 触发器。

关于Oracle View 不可更新,关于 Instead Of 触发器的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5260148/

相关文章:

oracle - 无法使用 sqoop 列出 oracle 表名

sql - plsql 自定义数字格式

mysql - 返回该月的最后一天

json - Oracle Rest 数据服务以 JSON 形式返回集合

mysql - 错误消息 "ORA-02270: no matching unique or primary key for this column-list"

sql - 编译和刷新物化 View 有什么区别?

sql - 等式查询

oracle - 在 Oracle 中从十六进制编码的 CLOB 转换为 BLOB

sql - 引用游标类型 oracle

sql - Oracle:有没有办法使用 unix crypt 方法对值进行编码?