Созданную вспомогательную таблицу заполним данными, используя уникальные идентификаторы, автоматически назначенные узлам иерархии при заполнении базовой таблицы.

NSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',0);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'BB31DC0F-BB57-48FF-B768-79D205F17F33',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'07EDFC1DE-BE2A-38BC86BA9EA2',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'07EDFC1DE-BE2A-38BC86BA9EA2',

'06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'777A3A0EB9-8B9D-325230D48A3A',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'777A3A0EB9-8B9D-325230D48A3A',

'06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'CF8D4BA4-89EB12-DDF2987D5949',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'CF8D4BA4-89EB12-DDF2987D5949',

'BB31DC0F-BB57-48FF-B768-79D205F17F33',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'9A42488B-536B-4269-A90C-BEB',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

НЕ нашли? Не то? Что вы ищете?

'9A42488B-536B-4269-A90C-BEB',

'BB31DC0F-BB57-48FF-B768-79D205F17F33',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'8E8CDC4F-A5A1-3DF2C25963AD',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'8E8CDC4F-A5A1-3DF2C25963AD',

'BB31DC0F-BB57-48FF-B768-79D205F17F33',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'D9826E05-BFD1-4845-AEFC-215C2E5BA78B',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',3);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'D9826E05-BFD1-4845-AEFC-215C2E5BA78B',

'06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'D9826E05-BFD1-4845-AEFC-215C2E5BA78B',

'07EDFC1DE-BE2A-38BC86BA9EA2',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'AF1A9E1A-4747-4BC1-A5F5-FA30272BD4A8',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',3);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'AF1A9E1A-4747-4BC1-A5F5-FA30272BD4A8',

'06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'AF1A9E1A-4747-4BC1-A5F5-FA30272BD4A8',

'777A3A0EB9-8B9D-325230D48A3A',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'AEB398A7-F653-4BE8-8844-AE9CAEC1A26F',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',3);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'AEB398A7-F653-4BE8-8844-AE9CAEC1A26F',

'06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'AEB398A7-F653-4BE8-8844-AE9CAEC1A26F',

'777A3A0EB9-8B9D-325230D48A3A',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'2520E3D9-B40F-4A6A-ADD8-A334CABCFBB2',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',3);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'2520E3D9-B40F-4A6A-ADD8-A334CABCFBB2',

'06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'2520E3D9-B40F-4A6A-ADD8-A334CABCFBB2',

'777A3A0EB9-8B9D-325230D48A3A',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'561D8DECC-BA0E-CE4CC204705B',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',3);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'561D8DECC-BA0E-CE4CC204705B',

'BB31DC0F-BB57-48FF-B768-79D205F17F33',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'561D8DECC-BA0E-CE4CC204705B',

'CF8D4BA4-89EB12-DDF2987D5949',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'0FBD7863-B4B5-456A-8FAC-63B972AAD010',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',3);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'0FBD7863-B4B5-456A-8FAC-63B972AAD010',

'BB31DC0F-BB57-48FF-B768-79D205F17F33',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'0FBD7863-B4B5-456A-8FAC-63B972AAD010',

'9A42488B-536B-4269-A90C-BEB',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'5BDF65BEF3-BBB1-B3BA8B48287B',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',3);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'5BDF65BEF3-BBB1-B3BA8B48287B',

'BB31DC0F-BB57-48FF-B768-79D205F17F33',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'5BDF65BEF3-BBB1-B3BA8B48287B',

'9A42488B-536B-4269-A90C-BEB',1);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'FC579270-CADA3-BEA0F5DB6E24',

'7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4',3);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'FC579270-CADA3-BEA0F5DB6E24',

'BB31DC0F-BB57-48FF-B768-79D205F17F33',2);

INSERT INTO T_Helper (UID, ParentID, Level) VALUES (

'FC579270-CADA3-BEA0F5DB6E24',

'8E8CDC4F-A5A1-3DF2C25963AD',1);

Таблица 8

Вспомогательная таблица T_Helper после заполнения данными

UID

ParentID

Level

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

0

06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

1

BB31DC0F-BB57-48FF-B768-79D205F17F33

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

1

07EDFC1DE-BE2A-38BC86BA9EA2

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

2

07EDFC1DE-BE2A-38BC86BA9EA2

06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F

1

777A3A0EB9-8B9D-325230D48A3A

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

2

777A3A0EB9-8B9D-325230D48A3A

06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F

1

CF8D4BA4-89EB12-DDF2987D5949

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

2

CF8D4BA4-89EB12-DDF2987D5949

BB31DC0F-BB57-48FF-B768-79D205F17F33

1

9A42488B-536B-4269-A90C-BEB

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

2

9A42488B-536B-4269-A90C-BEB

BB31DC0F-BB57-48FF-B768-79D205F17F33

1

8E8CDC4F-A5A1-3DF2C25963AD

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

2

8E8CDC4F-A5A1-3DF2C25963AD

BB31DC0F-BB57-48FF-B768-79D205F17F33

1

D9826E05-BFD1-4845-AEFC-215C2E5BA78B

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

3

D9826E05-BFD1-4845-AEFC-215C2E5BA78B

06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F

2

D9826E05-BFD1-4845-AEFC-215C2E5BA78B

07EDFC1DE-BE2A-38BC86BA9EA2

1

AF1A9E1A-4747-4BC1-A5F5-FA30272BD4A8

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

3

AF1A9E1A-4747-4BC1-A5F5-FA30272BD4A8

06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F

2

AF1A9E1A-4747-4BC1-A5F5-FA30272BD4A8

777A3A0EB9-8B9D-325230D48A3A

1

AEB398A7-F653-4BE8-8844-AE9CAEC1A26F

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

3

AEB398A7-F653-4BE8-8844-AE9CAEC1A26F

06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F

2

AEB398A7-F653-4BE8-8844-AE9CAEC1A26F

777A3A0EB9-8B9D-325230D48A3A

1

2520E3D9-B40F-4A6A-ADD8-A334CABCFBB2

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

3

2520E3D9-B40F-4A6A-ADD8-A334CABCFBB2

06B5F4F9-4B40-4CC2-982F-F258CDAEBB1F

2

2520E3D9-B40F-4A6A-ADD8-A334CABCFBB2

777A3A0EB9-8B9D-325230D48A3A

1

561D8DECC-BA0E-CE4CC204705B

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

3

561D8DECC-BA0E-CE4CC204705B

BB31DC0F-BB57-48FF-B768-79D205F17F33

2

561D8DECC-BA0E-CE4CC204705B

CF8D4BA4-89EB12-DDF2987D5949

1

0FBD7863-B4B5-456A-8FAC-63B972AAD010

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

3

0FBD7863-B4B5-456A-8FAC-63B972AAD010

BB31DC0F-BB57-48FF-B768-79D205F17F33

2

0FBD7863-B4B5-456A-8FAC-63B972AAD010

9A42488B-536B-4269-A90C-BEB

1

5BDF65BEF3-BBB1-B3BA8B48287B

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

3

5BDF65BEF3-BBB1-B3BA8B48287B

BB31DC0F-BB57-48FF-B768-79D205F17F33

2

5BDF65BEF3-BBB1-B3BA8B48287B

9A42488B-536B-4269-A90C-BEB

1

FC579270-CADA3-BEA0F5DB6E24

7F3FF030-0E7D-4BFF-B560-B43CA5E12CE4

3

FC579270-CADA3-BEA0F5DB6E24

BB31DC0F-BB57-48FF-B768-79D205F17F33

2

FC579270-CADA3-BEA0F5DB6E24

8E8CDC4F-A5A1-3DF2C25963AD

1

Обратите внимание. Аналогично способу со структурой со ссылкой на предка столбец «Указатель на предка узла» содержит список всех узлов дерева, имеющих потомков.

Данная модель позволяет проще, чем в случае рекурсивного метода, но несколько сложнее, чем в случае метода правого и левого коэффициентов (из-за необходимости связывания двух таблиц), выполнять практически все выборки, специфические для иерархий.

Приведём несколько простых примеров таких выборок.

Выбор всех потомков для заданного узла (в примере это узел B) может быть осуществлен следующим предложением SQL:

SELECT T_Base. Node

FROM T_Base, T_Helper

WHERE T_Base. ID=T_Helper. UID and

T_Helper. ParentID=(SELECT ID FROM T_Base

WHERE Node='B');

Результат данного запроса представлен на рис. 76.

Рис. 76. Выборка всех потомков узла B

Выбор всех предков для заданного узла (в примере это узел J) осуществляется следующим образом:

SELECT T_Base. Node, T_Helper. Level

FROM T_Base, T_Helper

WHERE T_Base. ID=T_Helper. ParentID and

T_Helper. UID=(SELECT ID FROM T_Base

WHERE Node='J')

ORDER BY T_Helper. Level DESC;

Результат выполнения этого запроса представлен на рис. 77.

Рис. 77. Выбор всех предков узла J

Обратите внимание на схожесть этих запросов. Сравните эти запросы с решением данных задач в случае использования рекурсивной модели иерархии.

Выбор узлов, не имеющих потомков, реализуется, например, следующим образом:

SELECT DISTINCT T_Base. Node FROM T_Base, T_Helper

WHERE T_Base. ID=T_Helper. UID and T_Helper. UID NOT IN (

SELECT DISTINCT ParentID FROM T_Helper);

Результат выполнения этого запроса представлен на рис. 78.

Рис. 78. Узлы, не имеющие потомков

Обратите внимание, что данный запрос очень похож на запрос, который мы использовали для решения той же задачи в случае рекурсивной модели иерархии.

Теперь рассмотрим задачу отыскания ближайшего общего предка для двух заданных узлов. Пусть выбраны узлы I и K. Как видно на рис. 8, их ближайшим общим предком является узел B. Получим полный список общих предков для узлов I и K (рис. 79):

SELECT T_Base. Node, T_Helper. Level, T_Helper. ParentID

FROM T_Base, T_Helper

WHERE T_Base. ID=T_Helper. ParentID and

T_Helper. UID=(SELECT ID FROM T_Base WHERE Node='K') AND T_Helper. ParentID IN (

SELECT T_Helper. ParentID

FROM T_Base, T_Helper

WHERE T_Base. ID=T_Helper. ParentID and

T_Helper. UID=(

SELECT ID FROM T_Base WHERE Node='I'));

Рис. 79. Полный список общих предков узлов I и K

Из этого списка надо оставить единственную строку, в которой значение в столбце Level минимально. Окончательно получаем (рис. 80):

SELECT T_Base. Node, T_Helper. Level, T_Helper. ParentID

FROM T_Base, T_Helper

WHERE T_Base. ID=T_Helper. ParentID AND

T_Helper. UID=(SELECT ID FROM T_Base WHERE Node='K') AND

T_Helper. ParentID IN

(SELECT T_Helper. ParentID

FROM T_Base, T_Helper

WHERE T_Base. ID=T_Helper. ParentID AND

T_Helper. UID=(SELECT ID FROM T_Base WHERE Node='I')) AND

T_Helper. Level=(SELECT MIN(T_Helper. Level)

FROM T_Base, T_Helper

WHERE T_Base. ID=T_Helper. ParentID AND

T_Helper. UID=(SELECT ID FROM T_Base WHERE Node='K') AND

T_Helper. ParentID IN

(SELECT T_Helper. ParentID

FROM T_Base, T_Helper

WHERE T_Base. ID=T_Helper. ParentID AND

T_Helper. UID=(SELECT ID FROM T_Base WHERE Node='I')));

Рис. 80. Ближайший общий предок узлов I и K

Поддержка целостности структуры иерархии требует дополнительныx средств.

Приведём пример хранимой процедуры для добавления листьев в дерево (триггер и в этом случае неприменим, так как надо указывать непосредственного предка добавляемого узла):

CREATE PROCEDURE AddNode (@Parent VARCHAR, @New VARCHAR) AS

-- Добавляем лист

-- ВНИМАНИЕ! Тут должна быть проверка

-- входного параметра!

-- После каждой операции необходима проверка ошибок,

-- отсутствующая в данном примере!

BEGIN

DECLARE @ParentID uniqueidentifier;

DECLARE @NewID uniqueidentifier;

-- Транзакция

BEGIN TRANSACTION AddNodeTransaction;

-- Добавляем строку нового узла в базовую таблицу

INSERT INTO T_Base(Node) VALUES (@New);

-- Получаем уникальный идентификатор нового элемента

SELECT @NewID=ID FROM T_Base WHERE Node=@New;

-- Получаем уникальный идентификатор

-- родительского элемента

SELECT @ParentID=ID FROM T_Base WHERE Node=@Parent;

-- ВНИМАНИЕ! Тут должна быть проверка

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7