Re: Деpево
- From
- Миклашевич Антон (2:5020/400)
- To
- Vladimir Eremin (2:5054/37.63)
- Date
- 2005-02-11T07:31:10Z
- Area
- SU.DBMS.SQL
From: "Миклашевич Антон" <666@kamtel.ru>
Hello, Vladimir!
You wrote to Миклашевич Антон on Thu, 10 Feb 2005 23:22:50 +0300:
МА>> одна таблица, подробности попробуй поискать в инете. Накрайняк
могу
запостить код для MS SQL.
VE> Может в эху... Может быть еще кому понадобится... :)
Этта я и имел ввиду. Если к табличке будет цеплятся
другая табличка внешним ключом, в прицепляемой таблице кластерным делаем
индекс по полю внешнего ключа. Вставка, модификация, удаление -
осуществляется стандартными SQL операторами.
Выборка всех потомков (прямых и косвенных) осуществляется:
select
*
from
НечтоГруппыТЗ гтз
inner join
НечтоГруппы нг
on
гтз.Дочерний = нг.Ид
where
гтз.Родитель = <Ид того, чьи потомки нам нужны>
Вот собственно и само дерево:
CREATE TABLE [НечтоГруппы] (
[Ид] uniqueidentifier PRIMARY KEY CLUSTERED,
[ИдРодителя] uniqueidentifier NULL,
CONSTRAINT [CK_НечтоГруппы.Ид.ИдРодителя] CHECK ([Ид] <> [ИдРодителя])
)
GO
CREATE TABLE [НечтоГруппыТЗ] (
[Родитель] uniqueidentifier NULL ,
[Дочерний] uniqueidentifier NOT NULL,
CONSTRAINT [куинд_НечтоГруппыТЗ.Родитель.Дочерний] UNIQUE CLUSTERED
(
[Родитель],
[Дочерний]
)
)
GO
ALTER TABLE [НечтоГруппы] ADD
CONSTRAINT [вк_НечтоГруппы.Ид__НечтоГруппы.ИдРодителя] FOREIGN KEY
(
[ИдРодителя]
) REFERENCES [dbo].[НечтоГруппы] (
[Ид]
)
GO
ALTER TABLE [dbo].[НечтоГруппыТЗ] ADD
CONSTRAINT [вк_НечтоГруппы.Ид__НечтоГруппыТЗ.Дочерний] FOREIGN KEY
(
[Дочерний]
) REFERENCES [dbo].[НечтоГруппы] (
[Ид]
) ON DELETE CASCADE ,
CONSTRAINT [вк_НечтоГруппы.Ид__НечтоГруппыТЗ.Родитель] FOREIGN KEY
(
[Родитель]
) REFERENCES [dbo].[НечтоГруппы] (
[Ид]
)
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
create trigger НечтоГруппы_ТЗ_Апдейт on dbo.НечтоГруппы
--# with encryption
after update
as begin
set nocount on
-- Если модифицировали Ид родителя
if update(ИдРодителя) begin
-- Удалим все записи об обновленных группах и их потомках
delete
НечтоГруппыТЗ
from
НечтоГруппыТЗ гтз
inner join
(select
гтз1.Родитель,
гтз1.Дочерний
from
НечтоГруппыТЗ гтз1
inner join
deleted уд
on
гтз1.Родитель = уд.Ид
) as гтз2
on
гтз.Дочерний = гтз2.Дочерний
declare @tInsert table(
Ид uniqueidentifier primary key,
ИдРодителя uniqueidentifier null
)
declare @tInserted table(
Ид uniqueidentifier primary key
)
insert
НечтоГруппыТЗ(
Родитель,
Дочерний
)
select
null,
вст.Ид
from
@tInsert as вст
where
вст.ИдРодителя is null
insert
@tInsert(
Ид,
ИдРодителя
)
select
вст.Ид,
вст.ИдРодителя
from
inserted as вст
while @@rowcount > 0 begin
insert
НечтоГруппыТЗ(
Родитель,
Дочерний
)
select
тз.Родитель,
вст.Ид
from
@tInsert as вст
inner join
НечтоГруппыТЗ as тз
on
вст.ИдРодителя = тз.Дочерний
insert
НечтоГруппыТЗ(
Родитель,
Дочерний
)
select
вст.Ид,
вст.Ид
from
@tInsert as вст
insert
@tInserted(
Ид
)
select
Ид
from
@tInsert
delete
@tInsert
insert
@tInsert(
Ид,
ИдРодителя
)
select
тг.Ид,
тг.ИдРодителя
from
НечтоГруппы as тг
inner join
@tInserted as вст
on
тг.ИдРодителя = вст.Ид
delete
@tInserted
end -- while @@rowcount > 0
end -- if update(ИдРодителя)
end
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
create trigger НечтоГруппы_ТЗ_Вставка on dbo.НечтоГруппы
--# with encryption
after insert
as begin
set nocount on
-- Для корневых элементов вставляем замыкание на корень - на null,
-- а для дочерних само будет вставляться
insert
НечтоГруппыТЗ(
Родитель,
Дочерний
)
select
null,
вст.Ид
from
inserted as вст
where
вст.ИдРодителя is null
-- Вставляем ссылки всех родителей на новые дочерние элементы
insert
НечтоГруппыТЗ(
Родитель,
Дочерний
)
select
тз.Родитель,
вст.Ид
from
inserted as вст
inner join
НечтоГруппыТЗ as тз
on
вст.ИдРодителя = тз.Дочерний
-- Вставляем замыкание на себя
insert
НечтоГруппыТЗ(
Родитель,
Дочерний
)
select
вст.Ид,
вст.Ид
from
inserted as вст
end
GO
--- ifmail v.2.15dev5.3
* Origin: Demos online service (2:5020/400)
SEEN-BY: 46/50 50/203 520 450/159 186 1024 451/30 454/9 461/43 132 640 469/999
SEEN-BY: 4614/20 4616/3 4625/8 4627/10 5000/76 5000 5001/5001 5006/1 5007/1
SEEN-BY: 5010/53 70 5011/13 5012/23 5015/10 5019/31 5020/52 118 175 194 400
SEEN-BY: 5020/545 604 639 715 758 892 894 1042 1057 1200 1523 1604 1665 1909
SEEN-BY: 5020/1922 2013 2020 2238 4441 8383 12000 5021/29 5025/3 750 5026/10
SEEN-BY: 5026/14 45 5027/16 5029/32 5030/115 217 473 556 966 1063 1339 1900
SEEN-BY: 5031/47 5035/38 5036/1 34 5040/47 5042/13 5047/43 5049/1 5051/15
SEEN-BY: 5054/1 8 9 10 28 35 37 45 63 67 5055/95 5057/1 5059/37 5060/88
SEEN-BY: 5061/15 5062/1 5066/18 5069/7 5070/1222 5079/23 5080/68 1003 5081/2
SEEN-BY: 5082/6 5083/21 5084/32 5085/13 5090/106 5092/1 5099/133 6000/12 254
SEEN-BY: 6009/1
PATH: 5020/400 4441 545 5054/1 37