Проверка на дубликаты уникальных идентификаторов
Материал из GedeminWiki
(Различия между версиями)
SYSDBA (обсуждение | вклад) |
SYSDBA (обсуждение | вклад) |
||
| Строка 19: | Строка 19: | ||
FROM | FROM | ||
rdb$relation_fields rf | rdb$relation_fields rf | ||
| + | JOIN rdb$relations r ON r.rdb$relation_name = rf.rdb$relation_name | ||
JOIN rdb$index_segments idxs ON idxs.rdb$field_name = rf.rdb$field_name | 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$indices idx ON idx.rdb$index_name = idxs.rdb$index_name | ||
| Строка 27: | Строка 28: | ||
AND | AND | ||
rf.rdb$relation_name <> 'GD_RUID' | rf.rdb$relation_name <> 'GD_RUID' | ||
| + | /* | ||
| + | |||
| + | Тут должно быть условие на таблицы, в которых не соблюдается | ||
| + | условие уникальности ИД. | ||
| + | |||
| + | */ | ||
| + | AND | ||
| + | r.rdb$system_flag = 0 | ||
| + | AND | ||
| + | COALESCE(r.rdb$relation_type, 0) = 0 | ||
AND | AND | ||
NOT EXISTS( | NOT EXISTS( | ||
Версия 20:16, 22 декабря 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$relations r ON r.rdb$relation_name = rf.rdb$relation_name 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 r.rdb$system_flag = 0 AND COALESCE(r.rdb$relation_type, 0) = 0 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