Контроль целостности типов документов
Материал из GedeminWiki
(Различия между версиями)
SYSDBA (обсуждение | вклад) (Новая страница: «Приведенный ниже код создает для каждой таблицы документа триггер, который проверяет со…») |
SYSDBA (обсуждение | вклад) |
||
| (не показаны 5 промежуточных версий 1 участника) | |||
| Строка 4: | Строка 4: | ||
EXECUTE BLOCK | EXECUTE BLOCK | ||
AS | AS | ||
| − | |||
DECLARE VARIABLE id INTEGER; | DECLARE VARIABLE id INTEGER; | ||
DECLARE VARIABLE relname VARCHAR(1024); | DECLARE VARIABLE relname VARCHAR(1024); | ||
| − | DECLARE VARIABLE | + | DECLARE VARIABLE dtkeys VARCHAR(1024); |
BEGIN | BEGIN | ||
FOR | FOR | ||
| Строка 17: | Строка 16: | ||
gd_documenttype dt | gd_documenttype dt | ||
JOIN at_relations hr ON hr.id = dt.HEADERRELKEY | JOIN at_relations hr ON hr.id = dt.HEADERRELKEY | ||
| + | WHERE | ||
| + | hr.relationname STARTING WITH 'USR$' | ||
GROUP BY | GROUP BY | ||
1, 2 | 1, 2 | ||
INTO | INTO | ||
| − | :id, :relname, : | + | :id, :relname, :dtkeys |
DO BEGIN | DO BEGIN | ||
| − | + | EXECUTE STATEMENT | |
'CREATE OR ALTER TRIGGER gd_check_dt_' || :id || ' FOR ' || :relname || | 'CREATE OR ALTER TRIGGER gd_check_dt_' || :id || ' FOR ' || :relname || | ||
' ACTIVE ' || | ' ACTIVE ' || | ||
| Строка 31: | Строка 32: | ||
'BEGIN ' || | 'BEGIN ' || | ||
' SELECT documenttypekey FROM gd_document WHERE id = NEW.documentkey INTO :dtkey;' || | ' SELECT documenttypekey FROM gd_document WHERE id = NEW.documentkey INTO :dtkey;' || | ||
| − | ' IF (NOT (:dtkey IN (' || : | + | ' IF (NOT (:dtkey IN (' || :dtkeys || '))) THEN ' || |
' EXCEPTION gd_e_exception ''Document type doesn`t match table ' || :relname || ''';' || | ' EXCEPTION gd_e_exception ''Document type doesn`t match table ' || :relname || ''';' || | ||
| − | 'END' | + | 'END' |
| − | + | WITH AUTONOMOUS TRANSACTION; | |
END | END | ||
END | END | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| + | |||
| + | Впоследствии удалить созданные триггеры можно с помощью кода: | ||
| + | |||
| + | <syntaxhighlight lang="SQL"> | ||
| + | EXECUTE BLOCK | ||
| + | AS | ||
| + | DECLARE VARIABLE tn VARCHAR(256); | ||
| + | BEGIN | ||
| + | FOR | ||
| + | SELECT | ||
| + | rdb$trigger_name | ||
| + | FROM | ||
| + | rdb$triggers | ||
| + | WHERE | ||
| + | rdb$trigger_name STARTING WITH 'GD_CHECK_DT_' | ||
| + | INTO | ||
| + | :tn | ||
| + | DO BEGIN | ||
| + | EXECUTE STATEMENT | ||
| + | 'DROP TRIGGER ' || :tn | ||
| + | WITH AUTONOMOUS TRANSACTION; | ||
| + | END | ||
| + | END | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | Приведенная ниже хранимая процедура выводит список всех записей в таблицах документов, для которых в GD_DOCUMENT содержится неверный тип в поле DOCUMENTTYPEKEY. | ||
| + | |||
| + | <syntaxhighlight lang="SQL"> | ||
| + | CREATE OR ALTER PROCEDURE gd_p_detect_corrupted_docs | ||
| + | RETURNS( | ||
| + | relname VARCHAR(64), | ||
| + | documentkey INTEGER, | ||
| + | dtkey INTEGER, | ||
| + | expecteddtkey VARCHAR(256) | ||
| + | ) | ||
| + | AS | ||
| + | BEGIN | ||
| + | FOR | ||
| + | SELECT | ||
| + | hr.relationname, | ||
| + | LIST(dt.id) | ||
| + | FROM | ||
| + | gd_documenttype dt | ||
| + | JOIN at_relations hr ON hr.id = dt.HEADERRELKEY | ||
| + | WHERE | ||
| + | hr.relationname STARTING WITH 'USR$' | ||
| + | GROUP BY | ||
| + | 1 | ||
| + | INTO | ||
| + | :relname, :expecteddtkey | ||
| + | DO BEGIN | ||
| + | FOR | ||
| + | EXECUTE STATEMENT | ||
| + | 'SELECT t.documentkey, d.documenttypekey ' || | ||
| + | 'FROM ' || :relname || ' t ' || | ||
| + | ' JOIN gd_document d ON d.id = t.documentkey ' || | ||
| + | 'WHERE ' || | ||
| + | ' NOT d.documenttypekey IN (' || :expecteddtkey || ')' | ||
| + | INTO :documentkey, :dtkey | ||
| + | DO | ||
| + | SUSPEND; | ||
| + | END | ||
| + | END | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | Вывод данной процедуры можно записать в промежуточную таблицу для анализа и обработки. | ||
| + | |||
[[Category:База данных]] | [[Category:База данных]] | ||
Текущая версия на 13:09, 12 января 2018
Приведенный ниже код создает для каждой таблицы документа триггер, который проверяет соответствие этой таблицы типу документа из поля GD_DOCUMENT.DOCUMENTTYPEKEY:
EXECUTE BLOCK AS DECLARE VARIABLE id INTEGER; DECLARE VARIABLE relname VARCHAR(1024); DECLARE VARIABLE dtkeys VARCHAR(1024); BEGIN FOR SELECT hr.id, hr.relationname, LIST(dt.id) FROM gd_documenttype dt JOIN at_relations hr ON hr.id = dt.HEADERRELKEY WHERE hr.relationname STARTING WITH 'USR$' GROUP BY 1, 2 INTO :id, :relname, :dtkeys DO BEGIN EXECUTE STATEMENT 'CREATE OR ALTER TRIGGER gd_check_dt_' || :id || ' FOR ' || :relname || ' ACTIVE ' || ' AFTER INSERT OR UPDATE ' || ' POSITION 32000 ' || 'AS ' || ' DECLARE VARIABLE dtkey INTEGER = NULL; ' || 'BEGIN ' || ' SELECT documenttypekey FROM gd_document WHERE id = NEW.documentkey INTO :dtkey;' || ' IF (NOT (:dtkey IN (' || :dtkeys || '))) THEN ' || ' EXCEPTION gd_e_exception ''Document type doesn`t match table ' || :relname || ''';' || 'END' WITH AUTONOMOUS TRANSACTION; END END
Впоследствии удалить созданные триггеры можно с помощью кода:
EXECUTE BLOCK AS DECLARE VARIABLE tn VARCHAR(256); BEGIN FOR SELECT rdb$trigger_name FROM rdb$triggers WHERE rdb$trigger_name STARTING WITH 'GD_CHECK_DT_' INTO :tn DO BEGIN EXECUTE STATEMENT 'DROP TRIGGER ' || :tn WITH AUTONOMOUS TRANSACTION; END END
Приведенная ниже хранимая процедура выводит список всех записей в таблицах документов, для которых в GD_DOCUMENT содержится неверный тип в поле DOCUMENTTYPEKEY.
CREATE OR ALTER PROCEDURE gd_p_detect_corrupted_docs RETURNS( relname VARCHAR(64), documentkey INTEGER, dtkey INTEGER, expecteddtkey VARCHAR(256) ) AS BEGIN FOR SELECT hr.relationname, LIST(dt.id) FROM gd_documenttype dt JOIN at_relations hr ON hr.id = dt.HEADERRELKEY WHERE hr.relationname STARTING WITH 'USR$' GROUP BY 1 INTO :relname, :expecteddtkey DO BEGIN FOR EXECUTE STATEMENT 'SELECT t.documentkey, d.documenttypekey ' || 'FROM ' || :relname || ' t ' || ' JOIN gd_document d ON d.id = t.documentkey ' || 'WHERE ' || ' NOT d.documenttypekey IN (' || :expecteddtkey || ')' INTO :documentkey, :dtkey DO SUSPEND; END END
Вывод данной процедуры можно записать в промежуточную таблицу для анализа и обработки.