Google
 

Rabu, 17 Oktober 2007

Firebird System Table (Part VI)

Here maybe the last system table (that I really used in in my daily program) I would like to share, that system table is (I) called a "constraint system trigger" (I don't know the correct name for this data, so I just called like that ^_^ CMIIW). I usually also find the error in query that has the name like this "CHECK_xx", so to find the table that has this contraint then I create a view like this:

CREATE VIEW "vSYS_FindSystemTrigger"(
"triggerName",
"tableName",
"triggerInactive",
"triggerType")
AS
select r.rdb$trigger_name, r.rdb$relation_name, r.rdb$trigger_inactive, r.rdb$trigger_type
from rdb$triggers r
where r.rdb$system_flag = 4;

In that query I don't know the meaning of the "triggerType", so if one of you know the meaning of that field, please add a comment in here. It can give other Firebird users more knowledge :)

1 komentar:

Romkin mengatakan...

rdb$trigger_type traditional values:
1 - BEFORE INSERT
2 - AFTER INSERT
3 - BEFORE UPDATE
4 - AFTER UPDATE
5 - BEFORE DELETE
6 - AFTER DELETE
You can see description in RDB$types, where rdb$field_name = 'RDB$TRIGGER_TYPE'.
But in Firebird 1.5 encoding of field RDB$TRIGGER_TYPE has been extended to allow complex trigger actions (copy from Dmitry Yemanov's 'universal_triggers.txt'):
// trigger type prefixes
#define TRIGGER_BEFORE 0
#define TRIGGER_AFTER 1

// trigger type suffixes
#define TRIGGER_INSERT 1
#define TRIGGER_UPDATE 2
#define TRIGGER_DELETE 3

// that's how trigger action types are encoded
/*
bit 0 = TRIGGER_BEFORE/TRIGGER_AFTER flag,
bits 1-2 = TRIGGER_INSERT/TRIGGER_UPDATE/TRIGGER_DELETE (slot #1),
bits 3-4 = TRIGGER_INSERT/TRIGGER_UPDATE/TRIGGER_DELETE (slot #2),
bits 5-6 = TRIGGER_INSERT/TRIGGER_UPDATE/TRIGGER_DELETE (slot #3),
and finally the above calculated value is decremented

example #1:
TRIGGER_AFTER_DELETE =
= ((TRIGGER_DELETE << 1) | TRIGGER_AFTER) - 1 =
= ((3 << 1) | 1) - 1 =
= 0x00000110 (6)

example #2:
TRIGGER_BEFORE_INSERT_UPDATE =
= ((TRIGGER_UPDATE << 3) | (TRIGGER_INSERT << 1) | TRIGGER_BEFORE) - 1 =
= ((2 << 3) | (1 << 1) | 0) - 1 =
= 0x00010001 (17)

example #3:
TRIGGER_AFTER_UPDATE_DELETE_INSERT =
= ((TRIGGER_INSERT << 5) | (TRIGGER_DELETE << 3) | (TRIGGER_UPDATE << 1) | TRIGGER_AFTER) - 1 =
= ((1 << 5) | (3 << 3) | (2 << 1) | 1) - 1 =
= 0x00111100 (60)
*/

Note(s):
1. One-action triggers are fully compatible at ODS level with FB 1.0.
2. RDB$TRIGGER_TYPE encoding is order-dependant, i.e.
BEFORE INSERT OR UPDATE and BEFORE UPDATE OR INSERT will be coded differently,
although they have the same semantics and will be executed exactly the same way.
3. In multiple-action triggers both OLD and NEW contexts are available. If the
trigger invocation forbids one of them (e.g. OLD context for INSERT operation),
then all fields of that context will eveluate to NULL. If you assign to
unproper context, runtime exception will be thrown.
4. You may use new context variables INSERTING/UPDATEING/DELETING to check the
operation type at runtime.