Subject DDL Triggers
Author Adriano dos Santos Fernandes
Usage:
1) Log database changes for inspection or replication.
2) Enforce object name convention. For example, DBA decides that all
procedures should have prefix "SP_".
3) Implement (flexible) metadata security using exceptions.

Syntax:

CREATE TRIGGER <name> { BEFORE | AFTER } <ddl event> ...

<ddl event> ::=
ANY DDL EVENT
| <ddl event list>

<ddl event list> ::=
<ddl event item>
| <ddl event list> OR <ddl event item>
* There will be a limit on number of items on this list. If I'm not
wrong, it can have a max of 13 items.

<ddl event item> ::=
CREATE TABLE
| ALTER TABLE
| DROP TABLE
| CREATE PROCEDURE
| ALTER PROCEDURE
| DROP PROCEDURE
| CREATE FUNCTION
| ALTER FUNCTION
| DROP FUNCTION
| DECLARE EXTERNAL FUNCTION
| ALTER EXTERNAL FUNCTION
| DROP EXTERNAL FUNCTION
| CREATE TRIGGER
| ALTER TRIGGER
| DROP TRIGGER
| CREATE EXCEPTION
| ALTER EXCEPTION
| DROP EXCEPTION
| CREATE VIEW
| ALTER VIEW
| DROP VIEW
| CREATE DOMAIN
| ALTER DOMAIN
| DROP DOMAIN
| CREATE ROLE
| ALTER ROLE
| DROP ROLE
| CREATE INDEX
| ALTER INDEX
| DROP INDEX
| CREATE SEQUENCE
| ALTER SEQUENCE
| DROP SEQUENCE
| CREATE USER
| ALTER USER
| DROP USER
| CREATE COLLATION
| DROP COLLATION
| ALTER CHARACTER SET

DDL_TRIGGER context namespace
- DDL_EVENT: event name (<ddl event item>)
- OBJECT_NAME: metadata object name
- SQL_TEXT: sql statement text

Triggers are fired (from DYN or DdlNodes) in these moments:
- BEFORE triggers executes before system table changes.
- AFTER triggers executes just after system table changes.

The only practical difference from them should be that AFTER triggers
see updated metadata.

With CREATE OR ALTER statements, trigger is fired one time using the
CREATE or ALTER event based on previous existence of the object.
With RECREATE statements, trigger is fired for DROP (when object exists)
and for CREATE events.

Example:

create trigger t_ddl_proc_name before create procedure
as
declare object_name type of column rdb$procedures.rdb$procedure_name =
rdb$get_context('DDL_TRIGGER', 'OBJECT_NAME');
begin
if (object_name not starting with 'SP_') then
exception e 'Invalid procedure name: ' || object_name;
end!

Comments?


Adriano