Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 как сочинить триггер для такой простой задачи?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
есть таблица, простое двухуровневое дерево,
надо:

в триггере при вставке новой записи или изменении поля num (или всей записи для простоты)
в паренте или потомке - обновить сумму в паренте = сумма всех полей num парента и потомков .

Сервер - 2000.
Как красиво сделать?


IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[test]') AND type in (N'U'))
	DROP TABLE [dbo].[test]
GO
CREATE TABLE [dbo].[test]
(
	[id] [int] NOT NULL,
	[parent_id] [int] NULL,
	[num] [int] NULL,
	[total] [int] NULL,
	CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED ([id])
)
insert into [dbo].[test](id, parent_id,num)
select 1, NULL,1
union
select 2, NULL,2
union
select 3, 1, 3
union
select 4, 1, 4
union
select 5, 2 ,5
union
select 6, 2, 6
union
select 7,NULL,7
union
select 8, 1, 8

27 окт 09, 09:18    [7842006]     Ответить | Цитировать Сообщить модератору
 Re: как сочинить триггер для такой простой задачи?  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
Winnipuh
при вставке новой записи или изменении поля num (или всей записи для простоты)
в паренте или потомке - обновить сумму в паренте = сумма всех полей num парента и потомков .
Я ничего не понял
Шаг 0: Таблица пустая
Шаг 1: Вставляем парента со значением num == 0
Шаг 2: Добавляем ему потомка со значением num == 10; у парента станет num == 10
Шаг 3: Добавляем ему еще одного потомка со значением num == 10;
у парента станет num == 10(первый потомок)+10(второй потомок)+10(сам парент) = 30
27 окт 09, 10:11    [7842311]     Ответить | Цитировать Сообщить модератору
 Re: как сочинить триггер для такой простой задачи?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Паганель
Winnipuh
при вставке новой записи или изменении поля num (или всей записи для простоты)
в паренте или потомке - обновить сумму в паренте = сумма всех полей num парента и потомков .
Я ничего не понял
Шаг 0: Таблица пустая
Шаг 1: Вставляем парента со значением num == 0
Шаг 2: Добавляем ему потомка со значением num == 10; у парента станет num == 10
Шаг 3: Добавляем ему еще одного потомка со значением num == 10;
у парента станет num == 10(первый потомок)+10(второй потомок)+10(сам парент) = 30


ну да, типа такого.
Т.е. потомки - это как дополнение к паренту, и надо суммировать всех в кучу
27 окт 09, 10:13    [7842329]     Ответить | Цитировать Сообщить модератору
 Re: как сочинить триггер для такой простой задачи?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Winnipuh
Паганель
Winnipuh
при вставке новой записи или изменении поля num (или всей записи для простоты)
в паренте или потомке - обновить сумму в паренте = сумма всех полей num парента и потомков .
Я ничего не понял
Шаг 0: Таблица пустая
Шаг 1: Вставляем парента со значением num == 0
Шаг 2: Добавляем ему потомка со значением num == 10; у парента станет num == 10
Шаг 3: Добавляем ему еще одного потомка со значением num == 10;
у парента станет num == 10(первый потомок)+10(второй потомок)+10(сам парент) = 30


ну да, типа такого.
Т.е. потомки - это как дополнение к паренту, и надо суммировать всех в кучу


не num ,сумма в total

Шаг 3: Добавляем ему еще одного потомка со значением num == 10;
у парента станет total == 10(первый потомок)+10(второй потомок)+10(сам парент) = 30
27 окт 09, 10:14    [7842342]     Ответить | Цитировать Сообщить модератору
 Re: как сочинить триггер для такой простой задачи?  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
Ага, вот для чего total...
А что, если вообще отказаться от этого поля, а вычислять его при выборке данных ?
27 окт 09, 10:21    [7842419]     Ответить | Цитировать Сообщить модератору
 Re: как сочинить триггер для такой простой задачи?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Паганель
Ага, вот для чего total...
А что, если вообще отказаться от этого поля, а вычислять его при выборке данных ?


можно, но всё-таки.. я так сделал

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF  EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[tr_u_test]'))
	DROP TRIGGER [dbo].[tr_u_test]
GO
CREATE TRIGGER tr_u_test
   ON  dbo.test
   FOR UPDATE
AS 
BEGIN
declare @rows int
set @rows=@@ROWCOUNT
if @rows=0 return;
SET NOCOUNT ON;

declare @t table(id int)
insert into @t(id) select id from inserted
union
select distinct parent_id from inserted where parent_id is not null
update test set total=t2.total
from 
(select sum(num) as total,isnull(parent_id, id) as node_id from test 
where isnull(parent_id, id) in (select id from @t)
group by isnull(parent_id, id)) t2
where id=t2.node_id

END
GO
27 окт 09, 10:25    [7842454]     Ответить | Цитировать Сообщить модератору
 Re: как сочинить триггер для такой простой задачи?  [new]
Anddros
Member

Откуда:
Сообщений: 1077
total парента = num парента + total'ы всех непосредственных потомков. При таком подходе достаточно в триггере на update/insert достаточно слазить вниз не далее, чем на 1 уровень, в триггере на delete вниз лазить не надо. + и там и там придется пересчитать всех предков вверх по дереву.
27 окт 09, 10:33    [7842560]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить