sergq |
---|
Подскажите еще как получить имя поля, на котором check сработал. |
check может быть установлен на несколько полей, какое тогда выводить ?
Правильнее выводить условие этого чека (проверяемое выражение).
Кроме того, надо знать "механику" чеков. все они, за исключением not null-кляуз при определении полей, реализованы как триггеры с именами 'CHECK_nnn', срабатываемые before insert or update. А это значит, что в таблице rdb$triggers для каждого такого чека будет не одна, а две записи. И для вывода уникального списка потребуется применить distinct или group by.
Пример (not_null-кляузы здесь названы "внутренними", а check-констрейнты - "внешними" чеками)):
-- самый простой чек, "внутренний" (не виден в rdb$triggers):
recreate table t0a(f01 int not null);
-- этот чек уже виден в rdb$triggers, причем как два before-триггера: на insert и на update:
recreate table t0b(f02 int check(f02>0));
-- здесь поле проверяется уже два раза: 1) на not null, 2) на соотв-вие чеку:
recreate table t0c(f03 int not null check(f03>1));
-- проверка каждого из полей только на not null и двух полей вместе - на условие "внешнего" чека:
recreate table t0d(fd1 int not null, fd2 int not null, check(fd1+fd2 between 100 and 200));
-- то же самое, только "внешний" чек - именованный:
recreate table t0e(fe1 int not null, fe2 int not null, constraint t0e_chk check(fe1+fe2 between 123 and 456));
recreate table t0f(
ff1 int not null
,ff2 int not null
,constraint t0ff1_chk check(ff1 between 1 and 7)
,constraint t0ff2_chk check(ff2 between 1 and 7)
,constraint t0ff_both check( abs(ff1-ff2) between 0 and 2)
); -- более сложный вариант проверки: несколько "внешних" чеков на два not_null-поля
commit;
Query:
with c0 as(
select
rc.rdb$relation_name rel_name
,rc.rdb$constraint_name chk_name
,rc.rdb$constraint_type chk_type
--,'#'l
,cc.*
--,'#'ll,rt.rdb$trigger_sequence trg_seq,rt.rdb$trigger_type trg_type
,cast(tt.rdb$type_name as varchar(255)) trg_event
,iif(upper(rc.rdb$constraint_type)=upper('NOT NULL'),
lower(trim(cc.rdb$trigger_name)||' is '||rc.rdb$constraint_type),
cast(rt.rdb$trigger_source as varchar(255))
) check_condition
from rdb$relation_constraints rc
left join rdb$check_constraints cc on rc.rdb$constraint_name=cc.rdb$constraint_name
left join rdb$triggers rt on cc.rdb$trigger_name=rt.rdb$trigger_name
left join rdb$types tt on tt.rdb$field_name='RDB$TRIGGER_TYPE' and tt.rdb$type=rt.rdb$trigger_type
)
select distinct rel_name, chk_name, check_condition
from c0
Result:
REL_NAMEtCHK_NAMEtCHECK_CONDITION | T0AtINTEG_109tf01 is not null | T0BtINTEG_110tcheck(f02>0) | T0CtINTEG_111tf03 is not null | T0CtINTEG_112tcheck(f03>1) | T0DtINTEG_113tfd1 is not null | T0DtINTEG_114tfd2 is not null | T0DtINTEG_115tcheck(fd1+fd2 between 100 and 200) | T0EtINTEG_116tfe1 is not null | T0EtINTEG_117tfe2 is not null | T0EtT0E_CHKtcheck(fe1+fe2 between 123 and 456) | T0FtINTEG_118tff1 is not null | T0FtINTEG_119tff2 is not null | T0FtT0FF1_CHKtcheck(ff1 between 1 and 7) | T0FtT0FF2_CHKtcheck(ff2 between 1 and 7) | T0FtT0FF_BOTHtcheck( abs(ff1-ff2) between 0 and 2) |
|