Ограничения
При создании базы данных на таблицы могут быть наложены различные ограничения, это и ограничения ссылочной целостности и всевозможные проверки вводимых значений и, к примеру, ограничения NOT NULL.
Перечень ограничений можно получить из таблицы RDB$RELATION_CONSTRAINTS. Приведенный пример запроса возвращает наименование ограничения, его тип, наименование таблицы, на которую данное ограничение распространяется и индекс, если ограничение базируется на индексе.
SELECT RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE, RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME, RDB$RELATION_CONSTRAINTS.RDB$INDEX_NAME FROM RDB$RELATION_CONSTRAINTS ORDER BY RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME;
Следующий запрос возвращает CHECK ограничения.
SELECT RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE, RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME FROM RDB$RELATION_CONSTRAINTS WHERE ((RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE = 'CHECK'));
Ограничения, типа CHECK, построены на основе триггеров. Следующий запрос позволяет получить наименования данных триггеров. Имя триггера находится в поле RDB$CHECK_CONSTRAINTS.RDB$TRIGGER_NAME.
SELECT RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE, RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME, RDB$CHECK_CONSTRAINTS.RDB$TRIGGER_NAME FROM RDB$RELATION_CONSTRAINTS INNER JOIN RDB$CHECK_CONSTRAINTS ON (RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME = RDB$CHECK_CONSTRAINTS.RDB$CONSTRAINT_NAME) WHERE ((RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE = 'CHECK'));
Запрос, аналогичный предыдущему, позволяет выбрать NOT NULL ограничения, а также имена полей таблиц (RDB$CHECK_CONSTRAINTS.RDB$TRIGGER_NAME), на которые они распространены.
SELECT RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE, RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME, RDB$CHECK_CONSTRAINTS.RDB$TRIGGER_NAME FROM RDB$RELATION_CONSTRAINTS INNER JOIN RDB$CHECK_CONSTRAINTS ON (RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME = RDB$CHECK_CONSTRAINTS.RDB$CONSTRAINT_NAME) WHERE ((RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE = 'NOT NULL')) ORDER BY RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME;
Ограничения, типа PRIMARY KEY, FOREIGN KEY и UNIQUE, базируются на индексах. Следующий пример запроса позволяет выбрать такие ограничения вместе с наименованиями индексов, на которых они базируются.
SELECT RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE, RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME, RDB$RELATION_CONSTRAINTS.RDB$INDEX_NAME FROM RDB$RELATION_CONSTRAINTS WHERE (RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY') or (RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY') or (RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE = 'UNIQUE') ORDER BY RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME;
Таблица RDB$INDICES содержит связи между индексами PRIMARY KEY и FOREIGN KEY. Используя, эту информацию можно написать запрос, который покажет связи между таблицами, а также индексы, участвующие в формировании этих связей.
SELECT RDB$INDICES.RDB$RELATION_NAME, RDB$INDICES.RDB$INDEX_NAME, RDB$INDICES1.RDB$RELATION_NAME, RDB$INDICES1.RDB$INDEX_NAME FROM RDB$INDICES INNER JOIN RDB$INDICES RDB$INDICES1 ON (RDB$INDICES.RDB$FOREIGN_KEY = RDB$INDICES1.RDB$INDEX_NAME) ORDER BY RDB$INDICES.RDB$RELATION_NAME;
Изменив предыдущий запрос, а именно добавив в него таблицу RDB$RELATION_CONSTRAINTS, можно получить пары master-detail с информацией об индексах, участвующих в организации связи, и наименованиях ограничений.
SELECT RDB$INDICES.RDB$RELATION_NAME, RDB$INDICES.RDB$INDEX_NAME, RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE, RDB$INDICES1.RDB$RELATION_NAME, RDB$INDICES1.RDB$INDEX_NAME, RDB$RELATION_CONSTRAINTS1.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS1.RDB$CONSTRAINT_TYPE FROM RDB$INDICES INNER JOIN RDB$INDICES RDB$INDICES1 ON (RDB$INDICES.RDB$FOREIGN_KEY = RDB$INDICES1.RDB$INDEX_NAME) INNER JOIN RDB$RELATION_CONSTRAINTS RDB$RELATION_CONSTRAINTS1 ON (RDB$INDICES1.RDB$INDEX_NAME = RDB$RELATION_CONSTRAINTS1.RDB$INDEX_NAME) INNER JOIN RDB$RELATION_CONSTRAINTS ON (RDB$INDICES.RDB$INDEX_NAME = RDB$RELATION_CONSTRAINTS.RDB$INDEX_NAME) ORDER BY RDB$INDICES.RDB$RELATION_NAME;
Таблица RDB$ REF_CONSTRAINTS содержит список всех вторичных ключей с поставленными в соответствие первичными ключами. Использую этот факт можно написать еще один вариант запроса, который выдаст пары master-detail.
SELECT RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE, RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME, RDB$RELATION_CONSTRAINTS1.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS1.RDB$CONSTRAINT_TYPE, RDB$RELATION_CONSTRAINTS1.RDB$RELATION_NAME FROM RDB$REF_CONSTRAINTS INNER JOIN RDB$RELATION_CONSTRAINTS ON (RDB$REF_CONSTRAINTS.RDB$CONSTRAINT_NAME = RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME) INNER JOIN RDB$RELATION_CONSTRAINTS RDB$RELATION_CONSTRAINTS1 ON (RDB$REF_CONSTRAINTS.RDB$CONST_NAME_UQ = RDB$RELATION_CONSTRAINTS1.RDB$CONSTRAINT_NAME) ORDER BY RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME;
А вот так можно получить пары master-detail с указанием правил поведения при обновлении и удалении в master таблице.
SELECT RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_TYPE, RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME, RDB$RELATION_CONSTRAINTS1.RDB$CONSTRAINT_NAME, RDB$RELATION_CONSTRAINTS1.RDB$CONSTRAINT_TYPE, RDB$RELATION_CONSTRAINTS1.RDB$RELATION_NAME, RDB$REF_CONSTRAINTS.RDB$UPDATE_RULE, RDB$REF_CONSTRAINTS.RDB$DELETE_RULE FROM RDB$REF_CONSTRAINTS INNER JOIN RDB$RELATION_CONSTRAINTS ON (RDB$REF_CONSTRAINTS.RDB$CONSTRAINT_NAME = RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME) INNER JOIN RDB$RELATION_CONSTRAINTS RDB$RELATION_CONSTRAINTS1 ON (RDB$REF_CONSTRAINTS.RDB$CONST_NAME_UQ = RDB$RELATION_CONSTRAINTS1.RDB$CONSTRAINT_NAME) ORDER BY RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME;