Контроль целостности типов документов

Материал из GedeminWiki
(Различия между версиями)
Перейти к: навигация, поиск
Строка 40: Строка 40:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
В последствии удалить созданные триггеры можно с помощью кода:
+
Впоследствии удалить созданные триггеры можно с помощью кода:
  
 
<syntaxhighlight lang="SQL">
 
<syntaxhighlight lang="SQL">
Строка 63: Строка 63:
 
END
 
END
 
</syntaxhighlight>
 
</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(64)
 +
  )
 +
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:База данных]]

Версия 12:46, 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(64)
  )
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

Вывод данной процедуры можно записать в промежуточную таблицу для анализа и обработки.

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты