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
备注:
CREATE ANY TRIGGER
权限是 RATOR_MONITORING
在另一个模式中的 table 上创建触发器所必需的,
- 当我们在SQL*Plus中更改连接时,数据库会创建一个新会话供我们使用。在提交这些更改之前,在一个会话中所做的更改在另一个会话中不可见。
- 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
我有 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
备注:
CREATE ANY TRIGGER
权限是RATOR_MONITORING
在另一个模式中的 table 上创建触发器所必需的,- 当我们在SQL*Plus中更改连接时,数据库会创建一个新会话供我们使用。在提交这些更改之前,在一个会话中所做的更改在另一个会话中不可见。
- 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