powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
17 сообщений из 17, страница 1 из 1
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38645588
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообщем говоря.
Есть дедушки, у них куча сыновей, у сыновей куча внуков(три таблицы) с сылками внешний ключ (иннодб)

при удалении сына, внуки удаляються каскадно
при удалении деда, удаляються каскадно сыновья, и естественно по цепочке каскадно внуки.

и вот проблема. мне надо внуков не удалять, а поставить им вкачестве ссылки НУЛЛ, но я наталкиваюсь на другую проблему - для внуков должна быть уникальной пара - имя + ссылка_на_родителя(у одного папы не может быть два сына с одним именем)

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

1
Как быть?

2
ИЗНАЧАЛЬНО
удаление внуков нужно обрабатывать, но тригер сдесь не поможет, ибо не вызываеться при каскадных действиях. счас идёт добавка аля регистры 1С(сайт не связан с 1с, просто логика похожая) - при создании внука мы тригером увеличиваем значение(регистр) при удалении , должны обновить значение регистра.

думал пойти по пути, вместо каскадного удаления - сет нулл и плясать в событии, но тут делема
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38646878
artas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как при Сталине прям :-)

Штатными средствами, мне кажется, никак
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647070
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну если изменить логику и вместо вставки null - умножать на -1 ? и в дальнейшем, если надо, проверять не на null, а на <0 ?
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647213
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,
посмотрите http://sqlfiddle.com/#!2/aa219/1
Код: 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.
create table tree(
   tid int 
  ,pid int
  ,node varchar(100)
  );
create table tree_hist(
   tid int 
  ,pid int
  ,node varchar(100)
  ,usr  varchar(100)
  ,dt   datetime
  ,key USR(usr,dt,pid)
  );
insert tree (tid,pid,node) values
  (1,null,'001'),
  (2,1,'001002'),
  (3,1,'001003'),
  (4,2,'001002004'),
  (5,4,'001002004005'),
  (6,3,'001003006');
//
create trigger TR_tree_AD
after delete on tree
for each row begin
  if (old.tid is not null) then
    insert tree_hist(tid,pid,node,usr,dt) 
      select old.tid,old.pid,old.node,user(),now();
  end if;
end;
//
create trigger TR_treehist_AD
after delete on tree_hist
for each row begin
  update tree t
    join tree p on p.pid=t.tid
  set p.pid=null
    where t.pid=old.tid;
  update tree set tid=null where pid=old.tid;
end;
//
delete from tree where tid=2;
delete from tree_hist where usr=user() and dt>now()-interval 1 second;
delete from tree where tid is null;
//
delete from tree where tid=3;
//


Код: sql
1.
2.
select * from tree order by node;
select * from tree_hist;


TID PID NODE1 (null) 0015 (null) 0010020040056 3 001003006

TID PID NODE USR DT3 1 001003 user_2_aa219@www May 21 2014
1) 3 прямые команды delete
2) если кто-то выполнил только одну - вломить ему по самое небалуй и довыполнить две оставшихся
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647216
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
поправка: индекс для tree
Код: sql
1.
2.
3.
4.
5.
create table tree(
   tid int auto_increment null unique
  ,pid int
  ,node varchar(100)
  );
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647429
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cygapb-007alex564657498765453,
посмотрите http://sqlfiddle.com/#!2/aa219/1
Код: 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.
create table tree(
   tid int 
  ,pid int
  ,node varchar(100)
  );
create table tree_hist(
   tid int 
  ,pid int
  ,node varchar(100)
  ,usr  varchar(100)
  ,dt   datetime
  ,key USR(usr,dt,pid)
  );
insert tree (tid,pid,node) values
  (1,null,'001'),
  (2,1,'001002'),
  (3,1,'001003'),
  (4,2,'001002004'),
  (5,4,'001002004005'),
  (6,3,'001003006');
//
create trigger TR_tree_AD
after delete on tree
for each row begin
  if (old.tid is not null) then
    insert tree_hist(tid,pid,node,usr,dt) 
      select old.tid,old.pid,old.node,user(),now();
  end if;
end;
//
create trigger TR_treehist_AD
after delete on tree_hist
for each row begin
  update tree t
    join tree p on p.pid=t.tid
  set p.pid=null
    where t.pid=old.tid;
  update tree set tid=null where pid=old.tid;
end;
//
delete from tree where tid=2;
delete from tree_hist where usr=user() and dt>now()-interval 1 second;
delete from tree where tid is null;
//
delete from tree where tid=3;
//


Код: sql
1.
2.
select * from tree order by node;
select * from tree_hist;


TID PID NODE1 (null) 0015 (null) 0010020040056 3 001003006

TID PID NODE USR DT3 1 001003 user_2_aa219@www May 21 2014
1) 3 прямые команды delete
2) если кто-то выполнил только одну - вломить ему по самое небалуй и довыполнить две оставшихся


Сударь, я правильно понял суть идеи

1)идёт обычная команда удаления узла , назовём дедИван
2)тригер в таблицу истории удаления поставит запись дедИван с датой и кем был удалён

3)удаляем в истории записи которые мы(тот же юзер) только что(по полю дата) удалили
4)тригер в истории, всем детям ивана, в качестве айди поставит нулл + всем внукам ивана поставит ссылку на папу в нул

5)удаляем все записи где айди нулл(тобишь всех детей дедаИвана)

и как бы получаеться не до конца...там ведь дерево может быть вложеным на 100 уровней, на 1000.

В любом случае, фактически ты предлагаешь самому делать каскадное удаление
УДАЛЕНИЕ)просто пометка на удаление, аля ставим ссылку на папу нулл(делаем ничейным)

в цикле сборщик мусора делает
1)удалить всё. где айди нулл - тригер в хистори поставит айдишники удалённого
2)удалём все из хистори - тригер для удаляемых айдишников, пометит всех их детей на удаление , сделав их ничейными...

и тут опять натыкаемся на уникальный ключ который может нарушиться, а также ссылка на родителя - не может указывать на несуществующего родителя...
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647441
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453 ,

предлагаю поиграться с http://sqlfiddle.com/#!2/7bdeb5/1

-- чужие игры можно убрать модификацией в левом окне
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647512
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453Сударь, я правильно понял суть идеи

1)идёт обычная команда удаления узла , назовём дедИван
2)тригер в таблицу истории удаления поставит запись дедИван с датой и кем был удалён

3)удаляем в истории записи которые мы(тот же юзер) только что(по полю дата) удалили
4)тригер в истории, всем детям ивана, в качестве айди поставит нулл + всем внукам ивана поставит ссылку на папу в нул

5)удаляем все записи где айди нулл(тобишь всех детей дедаИвана)

и как бы получаеться не до конца...там ведь дерево может быть вложеным на 100 уровней, на 1000.

В любом случае, фактически ты предлагаешь самому делать каскадное удаление
УДАЛЕНИЕ)просто пометка на удаление, аля ставим ссылку на папу нулл(делаем ничейным)

в цикле сборщик мусора делает
1)удалить всё. где айди нулл - тригер в хистори поставит айдишники удалённого
2)удалём все из хистори - тригер для удаляемых айдишников, пометит всех их детей на удаление , сделав их ничейными...

и тут опять натыкаемся на уникальный ключ который может нарушиться, а также ссылка на родителя - не может указывать на несуществующего родителя...Что-то я не понимаю, почему " как бы получаеться не до конца ":
1. да, обычная команда на удаление: delete tree where id=p_Дед;
2. в момент удаления информация из записи копируется в историю (но только если id not null)
3. сразу же после удаления из tree удаляем из истории все, только что добавленное туда этим юзером
4. триггер удаления из истории делает 2 вещи:
4.1. для всех внуков устанавливает предком NULL (вариант - копирует предка из удаленной записи), тем самым внуки и их потомки становятся доступны при обходе дерева от корня
4.2. всем сыновьям ломает id (так как сразу удалить их не дает ограничение MySQL)
5. удаляем из tree всех у кого id сломан - неважно, кем он был сломан, они уже не нужны. Триггер на удаление в историю их не включит, так как id is null

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

про цикл со сборщиком мусора я не понял - анафигизм какой-то
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647611
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
исправлен триггер на удаление истории. Теперь достаточно 2 команды: удаление из дерева и очистка истории
Так же потомки привязываются к предкам, а не в корень дерева.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
create trigger TR_treehist_AD
after delete on tree_hist
for each row begin
  update tree t 
    join tree p on p.pid=t.tid
  set p.pid=old.pid
    where t.pid=old.tid;
  update tree set tid=null where pid=old.tid;
  delete from tree where tid is null;
end;
//
create procedure UP_tree_del (p_id int)
begin
  start transaction;
  delete from tree where tid=p_id;
  delete from tree_hist where usr=user() and dt>now()-interval 1 second;
  commit;
end;
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647631
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cygapb-007Что-то я не понимаю, почему " как бы получаеться не до конца ":
1. да, обычная команда на удаление: delete tree where id=p_Дед;
2. в момент удаления информация из записи копируется в историю (но только если id not null)
3. сразу же после удаления из tree удаляем из истории все, только что добавленное туда этим юзером
4. триггер удаления из истории делает 2 вещи:
4.1. для всех внуков устанавливает предком NULL (вариант - копирует предка из удаленной записи), тем самым внуки и их потомки становятся доступны при обходе дерева от корня
4.2. всем сыновьям ломает id (так как сразу удалить их не дает ограничение MySQL)
5. удаляем из tree всех у кого id сломан - неважно, кем он был сломан, они уже не нужны. Триггер на удаление в историю их не включит, так как id is null

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

про цикл со сборщиком мусора я не понял - анафигизм какой-то

ну так, а удаление нужно всей ветки. внуки, правнуки, итд..
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647641
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я понял где я вас запутал.

нафиг дедов и внуков.

дерево папок и файлы.

вот при удалении некого узла в дереве папок, удаляються каскадно все папки, файлы счас удаляються тоже каскадно, но нужно перейти на установку нулл вкачестве внешнего ключа. чтобы обработать каждый удаляемый файл.
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647645
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

и как я писал, просто каскадно ставить нулл не получиться, ибо легко нарваться на уникальность пары имя+внешний_ключ
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647651
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453Есть дедушки, у них куча сыновей, у сыновей куча внуков(три таблицы) с сылками внешний ключ (иннодб)

при удалении сына, внуки удаляються каскадно
при удалении деда, удаляються каскадно сыновья, и естественно по цепочке каскадно внуки.

и вот проблема. мне надо внуков не удалять, а поставить им вкачестве ссылки НУЛЛ , но я наталкиваюсь на другую проблему - для внуков должна быть уникальной пара - имя + ссылка_на_родителя(у одного папы не может быть два сына с одним именем)

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

Как быть?
alex564657498765453ну так, а удаление нужно всей ветки. внуки, правнуки, итд ..
Где правда ?
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647831
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cygapb-007,

яж дописал.... да, я сначала выразился так, что не было понятно

потом дописал, дерево папок и привязаны файлы к папкак. дерево папок каскадно удаляеться, а вот файлы каскадно нельзя, ибо надо их по штучно обработать ещо.
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38647840
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453Cygapb-007,

яж дописал.... да, я сначала выразился так, что не было понятно

потом дописал, дерево папок и привязаны файлы к папкак. дерево папок каскадно удаляеться, а вот файлы каскадно нельзя, ибо надо их по штучно обработать ещо.
информация о папках и файлах хранится в одной таблице? И нет поля "тип ноды" (файл/папка)?
Это я к тому, что нет ли возможности каскадно удалить только папки, а потом обработать файлы, привязанные к уже удаленным папкам?
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38648161
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во я тормоз alex564657498765453Есть дедушки, у них куча сыновей, у сыновей куча внуков( три таблицы ) с сылками внешний ключ (иннодб)А я все про деревья пишу... про три сосны

вроде это требуется? http://sqlfiddle.com/#!2/ff9bf/1
...
Рейтинг: 0 / 0
надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
    #38648627
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cygapb-007Во я тормоз alex564657498765453Есть дедушки, у них куча сыновей, у сыновей куча внуков( три таблицы ) с сылками внешний ключ (иннодб)А я все про деревья пишу... про три сосны

вроде это требуется? http://sqlfiddle.com/#!2/ff9bf/1

ох блин... я уже сам удивляюсь как я такое написал.

таблицы две. одна дерево(папки) другая листья файлы.

предлагаю, забыть ту ересь что я писал, а то там реально запутанно.
folders(idfolder,fk_idfolder,name)
files(idfile,fk_idfolder,name)

(fk_idfolder,name) unique key в обоих таблицах.

удаляет юзер папку, счас база каскадно все подпапки и файлы удалит. но мне теперь надо чтобы на удалении файла работал тригер, что при каскадном действии невозможно.
поэтому каскадно ставим файла НУЛЛ вкачестве ссылки на папку.
но будет нарушаться уникальность ключа

вот и надо бы както это обойти

чтобы
1)каскадно файлам ставился fk_idfolder = null
2)в базе не было дублей пары (fk_idfolder,name) : fk_idfolder is not null
--я не говорю про индекс уникальности, я говорю про дубля быть не должно, а способ достижения цели любой

тогда мы папки чистим каскадно делете, а файла ставим нул, а потом отдельно удалим.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / надо чтото типа on delete cascade set null on duplicate key set name = cancat(name,random)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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