
Inline adoc files when they are included exactly once. Also fix language tags because this inlining gives us better information on what language the code is written in.
103 lines
1.9 KiB
Plaintext
103 lines
1.9 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Calling ``++COMMIT++`` or ``++ROLLBACK++`` from within a trigger will lead to an ``++ORA-04092++`` exception, unless the trigger has its own autonomous transaction.
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,sql]
|
|
----
|
|
SET SERVEROUTPUT ON
|
|
|
|
CREATE TABLE accounts(
|
|
balance NUMBER
|
|
);
|
|
|
|
INSERT INTO accounts VALUES(0);
|
|
|
|
CREATE TABLE log(
|
|
message VARCHAR2(100)
|
|
);
|
|
|
|
CREATE TRIGGER beforeLogger
|
|
BEFORE UPDATE ON accounts
|
|
FOR EACH ROW
|
|
BEGIN
|
|
INSERT INTO log VALUES('Attempt to update the value from ' || :OLD.balance || ' to ' || :NEW.balance);
|
|
COMMIT; -- Noncompliant, will fail with a ORA-04092
|
|
END;
|
|
/
|
|
|
|
-- We want to be able to log any attempt to update the "accounts" table
|
|
BEGIN
|
|
UPDATE accounts SET balance = 100;
|
|
ROLLBACK; -- Ultimately, this update is rolled back, however we still want to log it
|
|
END;
|
|
/
|
|
|
|
SELECT * FROM log;
|
|
|
|
DROP TRIGGER beforeLogger;
|
|
|
|
DROP TABLE log;
|
|
|
|
DROP TABLE accounts;
|
|
----
|
|
|
|
|
|
=== Compliant solution
|
|
|
|
[source,sql]
|
|
----
|
|
SET SERVEROUTPUT ON
|
|
|
|
CREATE TABLE accounts(
|
|
balance NUMBER
|
|
);
|
|
|
|
INSERT INTO accounts VALUES(0);
|
|
|
|
CREATE TABLE log(
|
|
message VARCHAR2(100)
|
|
);
|
|
|
|
CREATE TRIGGER beforeLogger
|
|
BEFORE UPDATE ON accounts
|
|
FOR EACH ROW
|
|
DECLARE
|
|
PRAGMA AUTONOMOUS_TRANSACTION;
|
|
BEGIN
|
|
INSERT INTO log VALUES('Attempt to update the value from ' || :OLD.balance || ' to ' || :NEW.balance);
|
|
COMMIT; -- Compliant, commits the trigger's autonomous transaction, not the main one
|
|
END;
|
|
/
|
|
|
|
-- We want to be able to log any attempt to update the "accounts" table
|
|
BEGIN
|
|
UPDATE accounts SET balance = 100;
|
|
ROLLBACK; -- Ultimately, this update is rolled back, however we still want to log it
|
|
END;
|
|
/
|
|
|
|
SELECT * FROM log;
|
|
|
|
DROP TRIGGER beforeLogger;
|
|
|
|
DROP TABLE log;
|
|
|
|
DROP TABLE accounts;
|
|
----
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
Remove this call to "xxx".
|
|
|
|
|
|
endif::env-github,rspecator-view[]
|