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

Откуда: СПб
Сообщений: 323
Помогите, плз, разобраться.

Есть таблица с деревом:
create table dbo.t_test (
	   id                   int                  not null,
	   name                 nvarchar(512)        null,
	   parentid             int                  null,
	   node                 hierarchyid          null,
	   constraint pk_t_test primary key (id)
	)

К ней делаю триггер:
create trigger [dbo].[tii_test] on [dbo].[t_test] 
INSTEAD OF INSERT
AS
BEGIN

  INSERT INTO t_test(id,name,parentid,node)
  SELECT 
   id,name,parentid,
    -- определяем ноду
    case  
      -- если предок не задан, то адрес узла верхнего уровня
      when parentid is null then (select hierarchyid::GetRoot())
      -- если предок задан, то адрес очередного (нового) дочернего узла 
      else (select node 
            from t_test 
            where id = inserted.parentid).GetDescendant((select max(node) 
                                                         from t_test
                                                         where node.GetAncestor(1)= (select node 
                                                                                     from t_test 
                                                                                     where id = inserted.parentid))
                                                         ,null)  
    end
  FROM inserted
  
END

При вставке записей по одной в каждый узел - все хорошо:
insert into t_test(id,name,parentid)
values(1,'РФ',null);

insert into t_test(id,name,parentid)
values(2,'СПб',1);

insert into t_test(id,name,parentid)
values(3,'Мск',1);

insert into t_test(id,name,parentid)
select 4,'Улица в Мск',3
union all
select 5,'Улица в СПб',2;

select t.*,t.node.ToString() from t_test t


Однако при попытке вставить сразу несколько записей в один узел вылезает косяк :(

insert into t_test(id,name,parentid)
select 6,'Дом в Мск 1',4
union all
select 7,'Дом в Мск 2',4
union all
select 8,'Дом в СПб 1',5
union all
select 9,'Дом в СПб 2',5;


select t.*,t.node.ToString() from t_test t

Как надо исправить триггер, что бы работало корректно?
5 янв 10, 22:02    [8150723]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с определением hierarchyid в триггере instead of insert  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Aleksey Kh.
Однако при попытке вставить сразу несколько записей в один узел вылезает косяк :(
Ага, вылезает в чистом поле из-за угла.
Вам не нравиться, что возвращается одинаковые значения? А разве так небыло задумано?
Судя по триггеру, начиная от GetRoot() и заканчивая GetDescendant(), именно так и надо.

Если вы хотите уникальности, первое и самое главное, поставьте ключ на поле "Node", и до второго уже не доходит, так как если нет ключа или хотябы индекса и сортировки в нём, зачем вам вообще сдался этот Hierarchyid? Уверен на 90% что если используется GetDescendant() только с заданным вторым параметром как NULL -- то чел явно не сечёт поляны.

Aleksey Kh.
Есть таблица с деревом
Голубые ели голубые брюки.
Прежде чем чем либо пользоваться желательно понимать как оно работает, для закрепления материала.

Стратегий генерации две, авто-инкремент с единственным методом (не считая TimeStamp) - определяется через Identity, и по стратегии "вероятного непопадания" - NewID() для UniqueIdentifier.
Hierarchyid это тупо бинарное значение для которых есть набор детерминированных функций.

Опять же стратегий несколько, например один - ограничение на вставку, или другой - "депараллелизация", много-шаговая вставка (эмуляция Identity). Надо ли решать проблему вставки сразу нескольких строк, если всё равно проблема вылезет при одновременной вставке в разных сессиях?
Смешанный подход ? (Оно вам надо?) Тогда итеративный код нужен, возможно даже CTE прокатит: для отсортированной группы определяем HID по цепочке, хотя толку от CTE мало.

И ещё, если есть уникальный Node, зачем тогда "ID" и "ParentID"?
При наличие "ParentID" и отсутствием авто-инкремента можно ещё контрольный пример наваять, когда потомки вставляются вместе с родителями.
6 янв 10, 02:07    [8151166]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с определением hierarchyid в триггере instead of insert  [new]
Aleksey Kh.
Member

Откуда: СПб
Сообщений: 323
Mnior
Вам не нравиться, что возвращается одинаковые значения? А разве так небыло задумано?

Неа :)

Mnior
Уверен на 90% что если используется GetDescendant() только с заданным вторым параметром как NULL -- то чел явно не сечёт поляны.

Для решения текущей проблемы не нужно "упорядочивание" по "name" :)

Ушел думать, про перенос в after insert
6 янв 10, 07:56    [8151251]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с определением hierarchyid в триггере instead of insert  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Aleksey Kh.
Для решения текущей проблемы не нужно "упорядочивание" по "name" :)
Так мы и услышали шо це за проблема.
6 янв 10, 23:20    [8153509]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить