Как динамически перемещаться по иерархии отношений внешнего ключа таблицы в SQL базе данных сервера, чтобы получить окончательную родительскую запись? - PullRequest
2 голосов
/ 06 января 2020

Я работаю в компании, в которой есть отдел управления проектами, которому необходимо периодически получать c обновления по электронной почте об изменениях, происходящих в нашей базе данных. База данных структурирована с достаточным количеством взаимосвязей внешних ключей, которые приводят к довольно сложному набору взаимосвязей, которые все находятся под таблицей «Проект».

Кроме того, у нас есть таблица «Контакт», которая во многих отношениях связана с нашей таблицей «Проект» через таблицу «Contact_Relationship». Эта таблица поддерживает тип отношения, а также саму связь. Предположим, что все остальные подтаблицы, подтаблицы и т. Д. находится в отношении один ко многим с таблицей над ней в иерархии.

См. Здесь слишком упрощенный пример:

Project
     Contact_Relationship
     Subtable1
          Subsubtable1
     Subtable2
          Subsubtable2
          Subsubtable3

Мне было поручено внедрить систему обмена сообщениями об обновлениях, которая периодически опрашивает изменения в записи проекта или в любом из его подпунктов и сообщений сообщение. Чтобы выполнить sh, мне нужно реализовать процедуру, чтобы получить конечную родительскую запись в таблице «Project» записи в любой из применимых таблиц, найти записи «Contact_Relationship», где тип «Менеджер проекта», а затем верните эти записи, чтобы я мог опубликовать сообщение об обновлении с соответствующими контактами. Теперь, учитывая, что структура subtables, sububtables, et c. в базе данных находится в постоянном развитии и, несомненно, увидит больше таблиц, добавленных в будущем, есть ли способ построить динамический запрос c, используя какое-то перекрестное применение к SQL административным таблицам сервера, чтобы получить конечную родительскую запись из какого-либо потенциального субтаблицы или субабаблета Неужели я здесь не в своей тарелке и есть гораздо более простое и очевидное решение? Я застрял в этой проблеме какое-то время и начинаю прибегать к срокам, чтобы реализовать все это, и я обеспокоен тем, что SQL знание, требуемое здесь, в настоящее время находится за пределами моей досягаемости.

В отличие от вопроса Получить Root родительский дочерний элемент в иерархической таблице , в этом случае я пересекаю отношения внешнего ключа между таблицами, а не родительско-дочерние отношения в той же таблице.

1 Ответ

1 голос
/ 06 января 2020

Вы можете применить идею иерархической навигации из той же таблицы к таблицам в INFORMATION_SCHEMA. Например, это (взято из 864696 ):

WITH MyCTE AS (
SELECT 
     KCU1.CONSTRAINT_SCHEMA AS FK_CONSTRAINT_SCHEMA 
    ,KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME 
    ,KCU1.TABLE_SCHEMA AS FK_TABLE_SCHEMA 
    ,KCU1.TABLE_NAME AS FK_TABLE_NAME 
    ,KCU1.COLUMN_NAME AS FK_COLUMN_NAME 
    ,KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION 
    ,KCU2.CONSTRAINT_SCHEMA AS REFERENCED_CONSTRAINT_SCHEMA 
    ,KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME 
    ,KCU2.TABLE_SCHEMA AS REFERENCED_TABLE_SCHEMA 
    ,KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME 
    ,KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME 
    ,KCU2.ORDINAL_POSITION AS REFERENCED_ORDINAL_POSITION 
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC 

INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU1 
    ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG  
    AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA 
    AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME 

INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU2 
    ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG  
    AND KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA 
    AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME 
    AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION 
)
...

Теперь вы можете применить иерархическую навигацию к этому.

...