У меня есть две таблицы с полями иерархии, одна из которых является промежуточной таблицей с новыми данными, которые необходимо объединить с другой (то есть набор узлов, которые необходимо добавить в основное дерево, некоторые из которыхможет уже быть там).
В дополнение к столбцу иерархии, который определяет древовидную структуру (родительские / дочерние отношения).Каждая таблица имеет отдельный столбец, который содержит идентификатор узла, который уникально идентифицирует каждый узел.То есть способ определить, находится ли узел из промежуточной таблицы в основной таблице, через идентификатор узла, а не через столбцы иерархии.
Обязательно, обработка, которая должна быть выполнена, будет выглядеть как-токак это:
For each row, RS, in the staging table:
If there is not already a row with the same Id as RS in the main table:
Find the parent, PS, of the staging row
Find the row, PM, in the main table that has the same node ID as PS
Create a new child, RM of row PM
Set PM's ID equal to the ID of RS
Важно, что этот подход будет работать только в том случае, если дерево в промежуточной таблице отсортировано / пройдено в порядке широты - это так, что при обнаружении RS гарантируется, что егоу родительского PS уже есть соответствующая строка в главной таблице.
До сих пор единственный способ добиться этого на SQL-сервере - это навести курсор на промежуточную таблицу (которая уже отсортирована) и вызватьхранимая процедура для каждой строки, которая по существу выполняет именно то, что описано выше, завершается SELECT MAX (), чтобы найти наивысший иерархический объект, который уже существует как дочерний элемент PM, чтобы дочерний элемент мог быть добавлен уникальным образом.
Это очень неэффективный подход и слишком медленный для моих целей.Есть ли лучший способ?
Для фона, это своего рода проверка осуществимости, которую я делаю.Мне нужно выяснить, могу ли я быстро выполнить эту операцию внутри SQL Server.Если окажется, что я не могу, мне придется сделать это по-другому, за пределами базы данных.Объединение деревьев присуще (на самом деле, в некотором смысле, является ) проблемной областью, поэтому структурирование данных по-разному или более широкое представление и попытка каким-либо образом избежать выполнения этой операции не являетсяопция.
Обновление
По запросу, вот конкретный пример.
Таблицы "staging" и "main" имеют одинаковые два столбца:
hierarchy_id of type hierarchyid
node_id of type bigint
Исходное содержание
основное:
hierarchy_id node_id
/1/ 1
/1/1/ 2
/1/2/ 3
/1/3/ 4
постановка:
hierarchy_id node_id
/1/ 1
/1/1/ 3
/1/2/ 5
/1/1/1/ 6
Желаемое содержимое
main:
hierarchy_id node_id
/1/ 1
/1/1/ 2
/1/2/ 3
/1/3/ 4
/1/4/ 5
/1/2/1/ 6
Обратите внимание, что узел в промежуточной таблице сierarchy_id / 1/1 / соответствует узлу hiearchy_id / 1/2 / в целевой таблице (именно поэтому важен идентификатор_узла - нельзя просто скопировать значения имя_иерархии).Также обратите внимание, что новый узел с node_id 6 добавляется в качестве дочернего элемента правильного родителя, а тот с node_id 3, поэтому важен иерархический идентификатор - он определяет древовидную структуру (отношения родитель / потомок) для любых новых узлов.Любое решение должно учитывать оба аспекта.