Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как получить список идентификаторов и типов каскадно удаляемых объектов? / 7 сообщений из 7, страница 1 из 1
11.09.2020, 14:30
    #39997654
teo609
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить список идентификаторов и типов каскадно удаляемых объектов?
Доброго здоровья всем.

Прошу помощи советом и по возможности кодом (сабж).
В тексте далее заменил uniqueidentifier на uuid для краткости.

Есть таблицы условно TREES, ROOTS, BRANCHES с полями
Код: sql
1.
TREES(tree_id uuid(PK), ...), ROOTS(root_id uuid(PK), tree_id(FK), ...), BRANCHES(branch_id uuid(PK), tree_id(FK), ...)



Есть ХП remove_tree(@tree_id) с кодом внутри
Код: sql
1.
delete from TREES where tree_id=@tree_id


Вызывается она из кода на С++


У таблицы TREES есть триггер с кодом
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
ALTER TRIGGER [dbo].[Trees_OnDelete]
ON [dbo].[TREES] AFTER DELETE
AS
BEGIN
delete ROOTS from ROOTS, deleted
	where ROOTS.tree_id = deleted.tree_id;
delete BRANCHES from BRANCHES, deleted
	where BRANCHES.branch_id = deleted.branch_id;
END	



Вопрос в том чтобы в С++ получить список удаляемых ROOTS и BRANCHES по типам
в таком виде
id type
uuid1, 1
uuid2, 1
uuid3, 2
uuid4, 2
uuid5, 2
где 1 и 2 условные типы удаляемых объектов, можно считать их константами

В идеале бы получить такой список в результате вызова ХП remove_order.
Т.е. без дополнительных вызовов из С++.

Единственный способ как его вообще получить, который я себе представляю как сделать, это
лочить таблицы ROOTS и BRANCHES в ХП remove_tree,
получать список объектов которые будут удалены,
вызывать удаление,
отпускать таблицы,
возвращать список.

Может быть, можно сделать лучше. Как?
...
Рейтинг: 0 / 0
11.09.2020, 16:22
    #39997702
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить список идентификаторов и типов каскадно удаляемых объектов?
teo609
Как?
Отказаться от триггера и удалять непосредственно в процедуре примерно так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
set xact_abort on;

declare @result table (id uniqueidentifier, [type] int);

begin tran;

delete TREES
output
 deleted.tree_id, 1 into @result (id, [type])
where
 tree_id = @tree_id;

delete r
output
 deleted.root_id, 2 into @t (id, [type])
from
 ROOTS r join
 @result t on r.tree_id = t.id and t.p[type] = 1;

delete b
output
 deleted.branch_id, 3 into @t (id, [type])
from
 BRANCHES b join
 @result t on b.tree_id = t.id and t.p[type] = 1;

commit;

select * from @result;



Есть еще вариант написать представление + instead of delete на него.
И удалять из представления, не забыв указать хинт updlock.
...
Рейтинг: 0 / 0
12.09.2020, 11:32
    #39997902
teo609
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить список идентификаторов и типов каскадно удаляемых объектов?
invm,

у меня придумался вариант перед

Код: sql
1.
2.
delete BRANCHES from BRANCHES, deleted
	where BRANCHES.branch_id = deleted.branch_id;



делать

Код: sql
1.
select into @temp_table (tree_id, item_id, item type) values @tree_id, deleted.branch_id, 2



а в хп потом

Код: sql
1.
2.
3.
select item id, item_type where tree_id=@tree_id;

delete @temp_table where tree_id=@tree_id



Такая идея должна работать?
Таблицу можно даже и постоянную иметь, это не страшно.

Как из триггера правильно обратиться к @tree_id?
deleted.tree_id - должен такой быть? В субботу нет под рукой рабочей базы.
...
Рейтинг: 0 / 0
12.09.2020, 12:06
    #39997904
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить список идентификаторов и типов каскадно удаляемых объектов?
teo609,

Вы спросили как лучше и получили ответ.
Если принципиально удалять детей триггером, при этом получить желаемое, то это, как уже говорилось, реализуется через представление. Вот пример:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
go

create table dbo.t1 (id int primary key);
create table dbo.t2 (id int primary key, t1_id int references dbo.t1(id));
create table dbo.t3 (id int primary key, t1_id int references dbo.t1(id));
go

create view dbo.vt
as
select id as t1_id, null as child_id, 1 as [type] from dbo.t1
union all
select t1_id, id, 2 from dbo.t2
union all
select t1_id, id, 3 from dbo.t3;
go

create trigger dbo.tr_vt
on dbo.vt
instead of delete
as
begin
 set nocount on;

 delete t3
 from
  dbo.t3 t3 join
  deleted d on d.child_id = t3.id and d.[type] = 3;

 delete t2
 from
  dbo.t2 t2 join
  deleted d on d.child_id = t2.id and d.[type] = 2;

 delete t1
 from
  dbo.t1 t1 join
  deleted d on d.t1_id = t1.id and d.[type] = 1;
end;
go

insert into dbo.t1 values (1), (2);
insert into dbo.t2 values (20, 1), (200, 2);
insert into dbo.t3 values (30, 1), (300, 2);

select 't1', * from dbo.t1;
select 't2', * from dbo.t2;
select 't3', * from dbo.t3;

declare @d table (t1_id int, child_id int, [type] int);
declare @t1_id int = 1;

delete dbo.vt with (updlock)
output
 deleted.t1_id, deleted.child_id, deleted.[type] into @d (t1_id, child_id, [type])
where
 t1_id = @t1_id;

select 'deleted child', * from @d where child_id is not null;

select 't1', * from dbo.t1;
select 't2', * from dbo.t2;
select 't3', * from dbo.t3;
go

drop view dbo.vt;
drop table dbo.t2, dbo.t3;
drop table dbo.t1;
go



Само-собой, вам никто не может запретить изобретать собственные велосипеды с квадратными колесами.
...
Рейтинг: 0 / 0
12.09.2020, 12:45
    #39997905
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить список идентификаторов и типов каскадно удаляемых объектов?
teo609
invm,

у меня придумался вариант перед

Код: sql
1.
2.
delete BRANCHES from BRANCHES, deleted
	where BRANCHES.branch_id = deleted.branch_id;



делать

Код: sql
1.
select into @temp_table (tree_id, item_id, item type) values @tree_id, deleted.branch_id, 2



а в хп потом
4
Код: sql
1.
2.
3.
select item id, item_type where tree_id=@tree_id;

delete @temp_table where tree_id=@tree_id



Такая идея должна работать?
Таблицу можно даже и постоянную иметь, это не страшно.

Как из триггера правильно обратиться к @tree_id?
deleted.tree_id - должен такой быть? В субботу нет под рукой рабочей базы.



То, что написано выше: в 2020 году - это трехколесный лисапед c квадратными колесами

https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-ver15
...
Рейтинг: 0 / 0
12.09.2020, 20:54
    #39997981
Ennor Tiegael
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить список идентификаторов и типов каскадно удаляемых объектов?
Ролг Хупин
То, что написано выше: в 2020 году - это трехколесный лисапед c квадратными колесами

https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-ver15
В случае, если версия сервера у ТС поддерживает output - да, безусловно.
...
Рейтинг: 0 / 0
14.09.2020, 10:43
    #39998223
teo609
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить список идентификаторов и типов каскадно удаляемых объектов?
Большое спасибо за помощь.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как получить список идентификаторов и типов каскадно удаляемых объектов? / 7 сообщений из 7, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]