Проверка на дубликаты уникальных идентификаторов

Материал из GedeminWiki
(Различия между версиями)
Перейти к: навигация, поиск
(Новая страница: «Идеология платформы требует чтобы у каждого бизнес-объекта был свой уникальный в предел…»)
 
Строка 68: Строка 68:
 
</sytaxhighlight>
 
</sytaxhighlight>
  
[[Category:База данных]]
+
[Category:База данных]

Версия 17:25, 20 декабря 2017

Идеология платформы требует чтобы у каждого бизнес-объекта был свой уникальный в пределах базы данных целочисленный идентификатор. Данное правило достигается с помощью использования единого генератора GD_G_UNIQUE. Однако, в результате программных сбоев могут возникнуть дубликаты ИД. Для их отыскания следует использовать запрос, приведенный ниже. Запрос выводит название таблицы и количество записей с ИД, встречающимся в других таблицах, в данной базе данных.

EXECUTE BLOCK
  RETURNS(tbl VARCHAR(31), cnt INTEGER)
AS
  DECLARE VARIABLE rn VARCHAR(31);
  DECLARE VARIABLE fn VARCHAR(31);
  DECLARE VARIABLE id INTEGER;
  DECLARE VARIABLE s INTEGER;
  DECLARE VARIABLE c INTEGER;
BEGIN
  IF (g_his_create(0, 0) = 0) THEN
    EXCEPTION gd_e_exception 'Can''t create huge array';
 
  FOR
    SELECT
      rf.rdb$relation_name, LIST(TRIM(rf.rdb$field_name))
    FROM
      rdb$relation_fields rf
      JOIN rdb$index_segments idxs ON idxs.rdb$field_name = rf.rdb$field_name
      JOIN rdb$indices idx ON idx.rdb$index_name = idxs.rdb$index_name
      JOIN rdb$relation_constraints rc ON rc.rdb$index_name = idx.rdb$index_name
        AND rc.rdb$relation_name = rf.rdb$relation_name
    WHERE
      rc.rdb$constraint_type = 'PRIMARY KEY'
      AND
      rf.rdb$relation_name <> 'GD_RUID'
      AND
      NOT EXISTS(
        SELECT * 
        FROM 
          rdb$index_segments idxs_fk 
          JOIN rdb$indices idx_fk ON idxs_fk.rdb$index_name = idx_fk.rdb$index_name
        WHERE
          idxs_fk.rdb$field_name = rf.rdb$field_name
          AND        
          idx_fk.rdb$relation_name = rf.rdb$relation_name
          AND
          idx_fk.rdb$index_name <> idx.rdb$index_name          
      )
    GROUP BY
      1
    HAVING
      LIST(TRIM(rf.rdb$field_name)) = 'ID'
  INTO
    :rn, :fn
  DO BEGIN
    s = 0;
    c = 0;
    EXECUTE STATEMENT
      'SELECT SUM(g_his_include(0, id)), COUNT(*) FROM ' || :rn || ' WHERE id > 147000000'
    INTO :s, :c;
 
    s = COALESCE(:s, 0);
    c = COALESCE(:c, 0);
 
    IF (:c <> :s) THEN
    BEGIN
      tbl = :rn;
      cnt = :c - :s;
      SUSPEND;
    END  
  END
 
  g_his_destroy(0);
END
</sytaxhighlight>
 
[Category:База данных]
Персональные инструменты
Пространства имён

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