Oracle 触发器不在另一个 table 中插入值

Oracle trigger not inserting values in another table

我有 SOAP_SERVICE table,如果新值被插入到这个 table 中,那么这些值也应该被插入到 SOAP_SERVICE_STATUS table 中。我正在为此编写下面的触发器,它没有任何错误并且编译成功。但是当我尝试将值插入 SOAP_SERVICE table 时,该值不会插入 SOAP_SERVICE_STATUS table.

create or replace TRIGGER RATOR_MONITORING.TRG_TRK_SOAP_SERVICE_STATUS
  AFTER INSERT 
 ON RATOR_MONITORING_CONFIGURATION.SOAP_SERVICE
 FOR EACH ROW
BEGIN
   INSERT INTO RATOR_MONITORING.SOAP_SERVICE_STATUS (SOAP_SERVICE_STATUS_ID,SOAP_SERVICE_ID,STATUS)
       VALUES (SOAP_SERVICE_STATUS_SEQ.nextval,:new.SOAP_SERVICE_ID,'N');
END;

抱歉,无法重现:

SQL> CREATE USER RATOR_MONITORING IDENTIFIED BY "password"
2            DEFAULT TABLESPACE USERS;

User created.

SQL> CREATE USER RATOR_MONITORING_CONFIGURATION IDENTIFIED BY "password"
2            DEFAULT TABLESPACE USERS;

User created.

SQL> GRANT CONNECT TO RATOR_MONITORING, RATOR_MONITORING_CONFIGURATION;

Grant succeeded.

SQL> GRANT CREATE TABLE TO RATOR_MONITORING, RATOR_MONITORING_CONFIGURATION;

Grant succeeded.

SQL> GRANT CREATE SEQUENCE TO RATOR_MONITORING;

Grant succeeded.

SQL> GRANT CREATE ANY TRIGGER TO RATOR_MONITORING;

Grant succeeded.

SQL> ALTER USER RATOR_MONITORING QUOTA UNLIMITED ON USERS;

User altered.

SQL> ALTER USER RATOR_MONITORING_CONFIGURATION QUOTA UNLIMITED ON USERS;

User altered.

SQL> CONNECT RATOR_MONITORING_CONFIGURATION/password
Connected.
SQL> CREATE TABLE RATOR_MONITORING_CONFIGURATION.SOAP_SERVICE (SOAP_SERVICE_ID INTEGER);

Table created.

SQL> CONNECT RATOR_MONITORING/password
Connected.
SQL> CREATE TABLE RATOR_MONITORING.SOAP_SERVICE_STATUS
2              (SOAP_SERVICE_STATUS_ID INTEGER, SOAP_SERVICE_ID INTEGER, STATUS CHAR(1));

Table created.

SQL> CREATE SEQUENCE RATOR_MONITORING.SOAP_SERVICE_STATUS_SEQ;

Sequence created.

SQL> create or replace TRIGGER RATOR_MONITORING.TRG_TRK_SOAP_SERVICE_STATUS
2       AFTER INSERT
3      ON RATOR_MONITORING_CONFIGURATION.SOAP_SERVICE
4      FOR EACH ROW
5     BEGIN
6        INSERT INTO RATOR_MONITORING.SOAP_SERVICE_STATUS (SOAP_SERVICE_STATUS_ID,SOAP_SERVICE_ID,STATUS)
7            VALUES (SOAP_SERVICE_STATUS_SEQ.nextval,:new.SOAP_SERVICE_ID,'N');
8     END;
9     /

Trigger created.

SQL> CONNECT RATOR_MONITORING_CONFIGURATION/password
Connected.
SQL> INSERT INTO RATOR_MONITORING_CONFIGURATION.SOAP_SERVICE (SOAP_SERVICE_ID) VALUES (7);

1 row created.

SQL> COMMIT;

Commit complete.

SQL> CONNECT RATOR_MONITORING/password
Connected.
SQL> SELECT * FROM RATOR_MONITORING.SOAP_SERVICE_STATUS;

SOAP_SERVICE_STATUS_ID SOAP_SERVICE_ID S
---------------------- --------------- -
                     1               7 N

备注:

  1. CREATE ANY TRIGGER 权限是 RATOR_MONITORING 在另一个模式中的 table 上创建触发器所必需的,
  2. 当我们在SQL*Plus中更改连接时,数据库会创建一个新会话供我们使用。在提交这些更改之前,在一个会话中所做的更改在另一个会话中不可见。
  3. SQL*Plus 在断开连接时隐式提交事务。在上面的示例中,我们在最后一个 CONNECT 之前显式提交,这样我们就不会依赖隐式行为。

最可能的解释是,您 select table RATOR_MONITORING.SOAP_SERVICE_STATUS 使用不同的连接,而没有提交在 RATOR_MONITORING_CONFIGURATION.SOAP_SERVICE 中执行插入的原始会话。 提交后记录应该可见。

另请注意,这是触发器与 table 处于不同模式这一事实的副作用;用户 RATOR_MONITORING_CONFIGURATION 可以在 table RATOR_MONITORING.SOAP_SERVICE_STATUS 中插入,即使 he/she 没有插入授权!

要启用此功能,用户 RATOR_MONITORING 必须拥有权限 create any trigger - 这并不总是被视为最佳实践(关于强大的权限) - 参见例如 Tom Kyte