A database-level trigger is a trigger associated with the entire database, rather than with one specific table or schema.
It is commonly used for:
- Database-wide DDL auditing
- Logon/logoff auditing
- Server-error auditing
- Preventing certain database-wide operations
- Monitoring database events
- Security and session initialization
The key idea is:
DATABASE
|
+-----------+-----------+
| | |
LOGON DDL SERVERERROR
| | |
+-----------+-----------+
↓
Database-level trigger
1. What is a database-level trigger?
A database-level trigger is a trigger that fires in response to database-wide events.
For example:
CREATE OR REPLACE TRIGGER trg_db_ddl
AFTER CREATE OR ALTER OR DROP ON DATABASE
BEGIN
DBMS_OUTPUT.PUT_LINE(
'Database DDL event occurred'
);
END;
/
This is different from:
AFTER CREATE ON SCHEMA
because:
SCHEMA trigger
↓
One schema
DATABASE trigger
↓
Database-wide scope
2. What is the difference between a database trigger and a schema trigger?
This is one of the most common interview questions.
Schema-level:
CREATE OR REPLACE TRIGGER trg_schema_ddl
AFTER CREATE OR ALTER OR DROP ON SCHEMA
BEGIN
...
END;
/
The trigger is associated with one schema.
Database-level:
CREATE OR REPLACE TRIGGER trg_db_ddl
AFTER CREATE OR ALTER OR DROP ON DATABASE
BEGIN
...
END;
/
The trigger is database-wide.
DDL EVENT
|
+---------+---------+
| |
SCHEMA DATABASE
TRIGGER TRIGGER
| |
One schema Whole database
3. What events can a database-level trigger handle?
Common database event triggers include:
DDL events:
CREATE
ALTER
DROP
TRUNCATE
ANALYZE
GRANT
REVOKE
Database/session events:
LOGON
LOGOFF
STARTUP
SHUTDOWN
SERVERERROR
The exact supported events depend on the Oracle trigger type and environment.
4. Can a database trigger handle INSERT, UPDATE and DELETE?
Not as a database event trigger.
Normal DML triggers are associated with tables:
CREATE OR REPLACE TRIGGER trg_emp
AFTER INSERT OR UPDATE OR DELETE ON employees
FOR EACH ROW
BEGIN
...
END;
/
Database-level event triggers are used for events such as:
CREATE
ALTER
DROP
LOGON
LOGOFF
STARTUP
SHUTDOWN
SERVERERROR
Think:
INSERT / UPDATE / DELETE
↓
Table trigger
CREATE / ALTER / DROP / LOGON
↓
Database event trigger
5. How do I create a database-wide DDL trigger?
Example:
CREATE OR REPLACE TRIGGER trg_database_ddl
AFTER CREATE OR ALTER OR DROP ON DATABASE
BEGIN
DBMS_OUTPUT.PUT_LINE(
'DDL event: ' || SYSEVENT
);
END;
/
Now a DDL operation such as:
CREATE TABLE test_table (
id NUMBER
);
can fire the trigger.
Likewise:
ALTER TABLE test_table
ADD name VARCHAR2(100);
or:
DROP TABLE test_table;
can fire it.
6. Can a database trigger determine which object was affected?
Yes.
Oracle provides event attributes such as:
SYSEVENT
ORA_DICT_OBJ_NAME
ORA_DICT_OBJ_TYPE
ORA_DICT_OBJ_OWNER
Example:
CREATE OR REPLACE TRIGGER trg_database_ddl
AFTER CREATE OR ALTER OR DROP ON DATABASE
BEGIN
DBMS_OUTPUT.PUT_LINE(
'Event = ' || SYSEVENT
);
DBMS_OUTPUT.PUT_LINE(
'Object = ' || ORA_DICT_OBJ_NAME
);
DBMS_OUTPUT.PUT_LINE(
'Object Type = ' || ORA_DICT_OBJ_TYPE
);
DBMS_OUTPUT.PUT_LINE(
'Owner = ' || ORA_DICT_OBJ_OWNER
);
END;
/
For:
CREATE TABLE employees (
employee_id NUMBER
);
You can get information conceptually like:
Event = CREATE
Object = EMPLOYEES
Object Type = TABLE
Owner = SCOTT
7. What is SYSEVENT?
SYSEVENT tells you which database event caused the trigger to fire.
For example:
CREATE OR REPLACE TRIGGER trg_db_event
AFTER CREATE OR ALTER OR DROP ON DATABASE
BEGIN
DBMS_OUTPUT.PUT_LINE(
'Event = ' || SYSEVENT
);
END;
/
Possible values can include:
CREATE
ALTER
DROP
depending on the triggering event.
8. What is ORA_DICT_OBJ_NAME?
It provides the name of the dictionary object associated with the event.
Example:
DBMS_OUTPUT.PUT_LINE(
ORA_DICT_OBJ_NAME
);
If:
CREATE TABLE employees (...);
causes the trigger to fire, the object name can be:
EMPLOYEES
9. What is ORA_DICT_OBJ_TYPE?
It provides the type of the affected dictionary object.
For example:
TABLE
VIEW
INDEX
PROCEDURE
FUNCTION
PACKAGE
TRIGGER
Example:
IF ORA_DICT_OBJ_TYPE = 'TABLE' THEN
DBMS_OUTPUT.PUT_LINE('Table DDL');
END IF;
10. What is ORA_DICT_OBJ_OWNER?
It identifies the owner of the dictionary object.
Example:
DBMS_OUTPUT.PUT_LINE(
'Owner = ' || ORA_DICT_OBJ_OWNER
);
This is particularly useful for a database-wide trigger because objects may belong to different schemas.
11. Can a database trigger audit DDL operations?
Yes.
This is one of the most common real-world uses.
Create an audit table:
CREATE TABLE database_ddl_audit (
username VARCHAR2(128),
event_name VARCHAR2(30),
object_owner VARCHAR2(128),
object_name VARCHAR2(128),
object_type VARCHAR2(30),
event_time TIMESTAMP
);
Create the trigger:
CREATE OR REPLACE TRIGGER trg_database_ddl_audit
AFTER CREATE OR ALTER OR DROP ON DATABASE
BEGIN
INSERT INTO database_ddl_audit
(
username,
event_name,
object_owner,
object_name,
object_type,
event_time
)
VALUES
(
ORA_LOGIN_USER,
SYSEVENT,
ORA_DICT_OBJ_OWNER,
ORA_DICT_OBJ_NAME,
ORA_DICT_OBJ_TYPE,
SYSTIMESTAMP
);
END;
/
Now suppose:
CREATE TABLE test_table (
id NUMBER
);
Then:
ALTER TABLE test_table
ADD name VARCHAR2(100);
And later:
DROP TABLE test_table;
The audit table can contain records such as:
USERNAME EVENT OWNER OBJECT TYPE
-------- ------ ----- ----------- ------
SCOTT CREATE SCOTT TEST_TABLE TABLE
SCOTT ALTER SCOTT TEST_TABLE TABLE
SCOTT DROP SCOTT TEST_TABLE TABLE
12. Can a database trigger prevent DDL?
Yes.
For example, suppose you want to prevent DROP operations.
CREATE OR REPLACE TRIGGER trg_prevent_drop
BEFORE DROP ON DATABASE
BEGIN
RAISE_APPLICATION_ERROR(
-20001,
'DROP operations are not allowed'
);
END;
/
Now:
DROP TABLE employees;
will be blocked by the trigger.
Conceptually:
DROP TABLE
↓
BEFORE DROP trigger
↓
RAISE_APPLICATION_ERROR
↓
DROP fails
13. Can we prevent dropping only certain objects?
Yes.
Example:
CREATE OR REPLACE TRIGGER trg_protect_tables
BEFORE DROP ON DATABASE
BEGIN
IF ORA_DICT_OBJ_TYPE = 'TABLE'
AND ORA_DICT_OBJ_NAME IN
('EMPLOYEES', 'DEPARTMENTS', 'PAYROLL')
THEN
RAISE_APPLICATION_ERROR(
-20010,
'This table is protected'
);
END IF;
END;
/
Now:
DROP TABLE employees;
is rejected.
But another object may not be affected by this particular condition.
14. Can a database trigger handle LOGON?
Yes.
A database-level logon trigger can execute when a user logs into the database.
Example:
CREATE OR REPLACE TRIGGER trg_db_logon
AFTER LOGON ON DATABASE
BEGIN
DBMS_OUTPUT.PUT_LINE(
'User logged in: ' || ORA_LOGIN_USER
);
END;
/
Because this is:
AFTER LOGON ON DATABASE
it has database-wide scope.
15. What is the difference between LOGON ON SCHEMA and LOGON ON DATABASE?
Schema-level:
AFTER LOGON ON SCHEMA
Applies to logons associated with that schema.
Database-level:
AFTER LOGON ON DATABASE
Applies database-wide.
ON SCHEMA
↓
Specific schema
ON DATABASE
↓
All applicable database sessions
This makes database-level logon triggers useful for centralized session initialization or auditing.
16. What is a common LOGON trigger use case?
One common use is setting application/session context.
Example:
CREATE OR REPLACE TRIGGER trg_db_logon
AFTER LOGON ON DATABASE
BEGIN
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => 'HR_APPLICATION',
action_name => 'LOGIN'
);
END;
/
This can help identify sessions in monitoring tools.
Another common use is auditing:
CREATE TABLE login_audit (
username VARCHAR2(128),
login_time TIMESTAMP
);
Trigger:
CREATE OR REPLACE TRIGGER trg_login_audit
AFTER LOGON ON DATABASE
BEGIN
INSERT INTO login_audit
(
username,
login_time
)
VALUES
(
ORA_LOGIN_USER,
SYSTIMESTAMP
);
END;
/
17. Can a database trigger handle LOGOFF?
Yes.
Example:
CREATE OR REPLACE TRIGGER trg_db_logoff
AFTER LOGOFF ON DATABASE
BEGIN
INSERT INTO login_audit
(
username,
login_time
)
VALUES
(
ORA_LOGIN_USER,
SYSTIMESTAMP
);
END;
/
In a real implementation, you'd normally use a separate audit table/columns for logoff events rather than calling the column login_time.
18. Can a database trigger handle STARTUP?
Yes.
A database event trigger can respond to startup events.
Example:
CREATE OR REPLACE TRIGGER trg_db_startup
AFTER STARTUP ON DATABASE
BEGIN
DBMS_OUTPUT.PUT_LINE(
'Database has started'
);
END;
/
Typical uses include:
- Database initialization
- Monitoring
- Startup auditing
- Session/environment setup
19. Can a database trigger handle SHUTDOWN?
Yes, where supported by the Oracle event-trigger model.
Example:
CREATE OR REPLACE TRIGGER trg_db_shutdown
BEFORE SHUTDOWN ON DATABASE
BEGIN
DBMS_OUTPUT.PUT_LINE(
'Database is shutting down'
);
END;
/
These types of triggers are normally used by DBAs for database lifecycle management and auditing.
20. Can a database trigger handle SERVERERROR?
Yes.
Example:
CREATE OR REPLACE TRIGGER trg_server_error
AFTER SERVERERROR ON DATABASE
BEGIN
INSERT INTO database_error_audit
(
username,
error_time
)
VALUES
(
ORA_LOGIN_USER,
SYSTIMESTAMP
);
END;
/
This can be useful for auditing certain database/server errors.
Oracle also provides error-related event functions such as:
ORA_SERVER_ERROR
ORA_SERVER_ERROR_MSG
for obtaining more information about the error.
21. Can we capture the actual Oracle error number?
Yes.
For example, Oracle provides:
ORA_SERVER_ERROR(1)
to retrieve an applicable server error code.
Example:
CREATE OR REPLACE TRIGGER trg_server_error
AFTER SERVERERROR ON DATABASE
BEGIN
INSERT INTO database_error_audit
(
username,
error_code,
error_time
)
VALUES
(
ORA_LOGIN_USER,
ORA_SERVER_ERROR(1),
SYSTIMESTAMP
);
END;
/
The exact error-stack handling should be designed carefully when implementing production auditing.
22. Can one database trigger handle multiple events?
Yes, depending on the supported event combination.
For DDL:
CREATE OR REPLACE TRIGGER trg_database_ddl
AFTER CREATE OR ALTER OR DROP ON DATABASE
BEGIN
DBMS_OUTPUT.PUT_LINE(
'Event = ' || SYSEVENT
);
END;
/
The trigger can determine the event using:
SYSEVENT
For example:
CREATE → CREATE
ALTER → ALTER
DROP → DROP
23. Can a database trigger use FOR EACH ROW?
No.
This is a very common interview question.
You don't write:
AFTER CREATE ON DATABASE
FOR EACH ROW
because DDL/database event triggers aren't row-level table triggers.
Correct:
CREATE OR REPLACE TRIGGER trg_db_ddl
AFTER CREATE ON DATABASE
BEGIN
...
END;
/
24. Can a database trigger use :OLD and :NEW?
No.
:OLD and :NEW are row-level DML correlation variables.
They are used with table triggers such as:
AFTER UPDATE ON employees
FOR EACH ROW
Database event triggers use event attributes instead:
SYSEVENT
ORA_DICT_OBJ_NAME
ORA_DICT_OBJ_TYPE
ORA_DICT_OBJ_OWNER
ORA_LOGIN_USER
25. Can a database trigger query dictionary views?
Yes, where appropriate.
For example:
SELECT COUNT(*)
FROM all_objects
WHERE owner = ORA_DICT_OBJ_OWNER;
However, you should be careful with queries and privileges in event triggers because these triggers can execute in sensitive database contexts.
26. Can a database trigger perform DML?
Yes.
This is common for auditing.
For example:
INSERT INTO database_ddl_audit
(
username,
event_name,
object_name
)
VALUES
(
ORA_LOGIN_USER,
SYSEVENT,
ORA_DICT_OBJ_NAME
);
The DML becomes part of the transaction/event processing.
27. Can a database trigger execute COMMIT?
No.
For example:
CREATE OR REPLACE TRIGGER trg_db_ddl
AFTER CREATE ON DATABASE
BEGIN
INSERT INTO database_ddl_audit (...);
COMMIT;
END;
/
A trigger cannot normally issue:
COMMIT
ROLLBACK
The trigger participates in the transaction context of the operation that caused it.
28. Can a database trigger call a procedure?
Yes.
Example:
CREATE OR REPLACE TRIGGER trg_db_ddl
AFTER CREATE OR ALTER OR DROP ON DATABASE
BEGIN
log_ddl_event(
ORA_LOGIN_USER,
SYSEVENT,
ORA_DICT_OBJ_NAME,
ORA_DICT_OBJ_TYPE
);
END;
/
Procedure:
CREATE OR REPLACE PROCEDURE log_ddl_event
(
p_username VARCHAR2,
p_event VARCHAR2,
p_object_name VARCHAR2,
p_object_type VARCHAR2
)
IS
BEGIN
INSERT INTO database_ddl_audit
(
username,
event_name,
object_name,
object_type,
event_time
)
VALUES
(
p_username,
p_event,
p_object_name,
p_object_type,
SYSTIMESTAMP
);
END;
/
This can keep complex trigger logic cleaner.
29. What is the difference between a table trigger, schema trigger, and database trigger?
This is one of the most important interview comparisons.
| Feature | Table Trigger | Schema Trigger | Database Trigger |
|---|---|---|---|
| Main purpose | Table DML | Schema events | Database-wide events |
| INSERT | ✅ | ❌ | ❌ |
| UPDATE | ✅ | ❌ | ❌ |
| DELETE | ✅ | ❌ | ❌ |
| CREATE | ❌ | ✅ | ✅ |
| ALTER | ❌ | ✅ | ✅ |
| DROP | ❌ | ✅ | ✅ |
| LOGON | ❌ | Possible | ✅ |
| STARTUP | ❌ | ❌ | ✅ |
| SHUTDOWN | ❌ | ❌ | ✅ |
:OLD / :NEW |
Row-level | ❌ | ❌ |
FOR EACH ROW |
Possible | ❌ | ❌ |
| Scope | Table | Schema | Database |
30. Database trigger vs schema trigger: example
Suppose there are three schemas:
HR
FINANCE
SALES
A schema trigger:
CREATE OR REPLACE TRIGGER trg_hr_ddl
AFTER CREATE ON SCHEMA
BEGIN
...
END;
/
is associated with one schema.
A database trigger:
CREATE OR REPLACE TRIGGER trg_all_ddl
AFTER CREATE ON DATABASE
BEGIN
...
END;
/
can monitor applicable DDL events across the database.
DATABASE
+------------+------------+
| | |
HR FINANCE SALES
| | |
schema schema schema
trigger trigger trigger
versus
DATABASE TRIGGER
↓
+---------+---------+
↓ ↓ ↓
HR FINANCE SALES
31. Can a database trigger protect production objects?
Yes.
For example:
CREATE OR REPLACE TRIGGER trg_protect_production
BEFORE DROP ON DATABASE
BEGIN
IF ORA_DICT_OBJ_OWNER = 'HR'
AND ORA_DICT_OBJ_NAME IN
('EMPLOYEES', 'PAYROLL')
THEN
RAISE_APPLICATION_ERROR(
-20050,
'Production object is protected'
);
END IF;
END;
/
This can add a safety layer against accidental DDL.
However, privileges, roles, deployment controls, and Oracle security features should be the primary protection mechanism. A trigger should not be the only defense.
32. What happens if the database trigger raises an exception?
Suppose:
CREATE OR REPLACE TRIGGER trg_block_drop
BEFORE DROP ON DATABASE
BEGIN
RAISE_APPLICATION_ERROR(
-20001,
'DROP is not allowed'
);
END;
/
Then:
DROP TABLE employees;
fails because the trigger raises an exception.
Execution flow:
DROP TABLE
↓
BEFORE DROP
↓
Exception
↓
DDL fails
33. Can multiple database triggers exist for the same event?
Yes, Oracle can have multiple triggers associated with events, subject to the applicable trigger rules and ordering options.
For example:
TRG_DDL_A
TRG_DDL_B
TRG_DDL_C
could all respond to a DDL event.
If execution order matters, Oracle provides trigger ordering mechanisms for applicable trigger types/versions. In practice, avoid relying on an arbitrary firing order unless you explicitly control it.
34. What is a good complete DDL-audit example?
Step 1: Create audit table
CREATE TABLE database_ddl_audit (
audit_id NUMBER GENERATED ALWAYS AS IDENTITY,
username VARCHAR2(128),
event_name VARCHAR2(30),
object_owner VARCHAR2(128),
object_name VARCHAR2(128),
object_type VARCHAR2(30),
event_time TIMESTAMP
);
Step 2: Create database trigger
CREATE OR REPLACE TRIGGER trg_database_ddl_audit
AFTER CREATE OR ALTER OR DROP ON DATABASE
BEGIN
INSERT INTO database_ddl_audit
(
username,
event_name,
object_owner,
object_name,
object_type,
event_time
)
VALUES
(
ORA_LOGIN_USER,
SYSEVENT,
ORA_DICT_OBJ_OWNER,
ORA_DICT_OBJ_NAME,
ORA_DICT_OBJ_TYPE,
SYSTIMESTAMP
);
END;
/
Step 3: Perform DDL
CREATE TABLE demo_table (
id NUMBER
);
Then:
ALTER TABLE demo_table
ADD name VARCHAR2(100);
Then:
DROP TABLE demo_table;
Step 4: Check audit
SELECT
username,
event_name,
object_owner,
object_name,
object_type,
event_time
FROM database_ddl_audit
ORDER BY audit_id;
You should see records representing:
CREATE
ALTER
DROP
35. What are common database-trigger interview traps?
Trap 1
Question: Does a database trigger fire once per row?
Answer: ❌ No.
Database event triggers respond to database events, not individual table rows.
Trap 2
Question: Can database triggers use :OLD and :NEW?
Answer: ❌ No.
Those are row-level DML variables.
Trap 3
Question: Can database triggers use FOR EACH ROW?
Answer: ❌ No.
They are event triggers rather than row-level table triggers.
Trap 4
Question: Can a database trigger audit CREATE TABLE?
Answer: ✅ Yes.
For example:
AFTER CREATE ON DATABASE
Trap 5
Question: Can a database trigger prevent DROP TABLE?
Answer: ✅ Yes.
For example:
BEFORE DROP ON DATABASE
followed by RAISE_APPLICATION_ERROR.
Trap 6
Question: Can a database trigger handle LOGON?
Answer: ✅ Yes.
AFTER LOGON ON DATABASE
Trap 7
Question: Can a database trigger handle STARTUP?
Answer: ✅ Yes.
AFTER STARTUP ON DATABASE
Trap 8
Question: Can a database trigger execute COMMIT?
Answer: ❌ No.
36. Database-level trigger cheat sheet
Memorize this:
DATABASE TRIGGER
----------------
Scope Entire database
CREATE ✅
ALTER ✅
DROP ✅
TRUNCATE ✅
LOGON ✅
LOGOFF ✅
STARTUP ✅
SHUTDOWN ✅
SERVERERROR ✅
INSERT ❌ Not table DML
UPDATE ❌ Not table DML
DELETE ❌ Not table DML
:OLD ❌
:NEW ❌
FOR EACH ROW ❌
COMMIT ❌
The easiest way to remember:
TABLE
↓
INSERT / UPDATE / DELETE
↓
TABLE TRIGGER
SCHEMA
↓
DDL events in one schema
↓
SCHEMA TRIGGER
DATABASE
↓
Database-wide events
↓
DATABASE TRIGGER
One-line interview answer
A database-level trigger is an event trigger defined at the database scope that responds to events such as DDL, LOGON, LOGOFF, STARTUP, SHUTDOWN, and SERVERERROR, rather than to individual table rows.
Most Important Distinction
Table Trigger
→ Row/data changes
Schema Trigger
→ Events in one schema
Database Trigger
→ Database-wide events
No comments:
Post a Comment