powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Триггер DELETE в случае группового удаления данных
17 сообщений из 42, страница 2 из 2
Триггер DELETE в случае группового удаления данных
    #38885869
EvgIq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
сизиф и мартышки,

Я ничего и никому не порчу. Я не павлович. Нечего сказать по существу - проходите мимо.
Я смотрю тут много подобных умников-философоф трется. А казалось бы технический форум.
И да, пока на дворе еще только поздняя зима, г-н сифиз и мартышки. Посмотрите в календарь, в окно, или куда там вас выпустят посмотреть. Опыт по обострениям видать у вас большой.
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38885903
EvgIq,

ну право слово, не стоит дуться
ну вот, случилось вам идея ощастливить мир -- щасливьте
я только за; и даже вот помогаю
а что не понимаете, что вам помогают именно технически -- тоже не беда

ещё раз:
если вам знаком MSSQL -- там в триггере на удаление (на весь стейтмент, а не на каждый рядок) -- вам проще будет высчитать "коллективные эффекты" (раз они вам мешают жить)
а в качестве бонуса -- вы не породите массу dead rows [в версионнике], которые постгресу, в норме, ни к чему, и если есть способы обсчистывать дерево без таких подарков от жениев не павловичей [а они есть], то люди будут пользоваться ими, а не вашим щасьем.
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38885912
EvgIq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
сизиф и мартышки,

Глобальные идеи для всемирного счастия я оставляю вам. И дабы не провоцировать очередной кризис у поциентов, уже впавших в раннее весеннее обострение, сообщаю - я буду складывать "дырки" в отдельную таблицу, и брать их оттуда когда нормальные id на уровне кончатся.
Свои же, неактуальные сейчас для меня, бестолковые, советы по выбору бд, оставьте, для коллег по палате. Для них же приберегите свои размышления о групповых операциях над ключем, особенно когда попытаетесь помочь реализовать, для всемирного опять же счастия, такие алгоритмы как "Nested Sets" и "Materialized Paths".
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38885956
EvgIq,

не огрызайтесь, деточка
если вы сбежали от санитаров, это не повод пытаться править миром

кодинг, это не гениальные идеи, а банальные рефлексы по их реализации
и, в т.ч. реализации даже далеко не жениальных идей

судя же по вашему коду -- вы нуб в бд вообще и в postgresql -- в частности
поэтому мсскл вам ничем не хуже.

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

Но к делу:
егоров правильно вам написал по мелочи:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
CREATE OR REPLACE FUNCTION const_ch()
  RETURNS integer AS
$BODY$	-- устанавливаем допустимое количество Детей у элемента в дереве
	SELECT 3;
$BODY$
LANGUAGE sql IMMUTABLE
COST 10;

CREATE OR REPLACE FUNCTION const_lv()
  RETURNS integer AS
$BODY$
	-- устанавливаем допустимое количество Уровней в дереве
	SELECT 4;
$BODY$
LANGUAGE sql IMMUTABLE
COST 10;



-- это конечно всё "не существенно", для изобретателей велосипедов, но когда база из за таких кодеров встаёт колом -- приходится доставать полено -- и заниматься промежушной педагогикой

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

Код: 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.
CREATE OR REPLACE FUNCTION new_id_board()
  RETURNS trigger AS
$BODY$DECLARE
	lv		integer;	-- количество уровней в дереве
	ch		integer;	-- допустимое количество детей
	id_new		bigint;		-- вычесляемый id нового элемента
	id_p		bigint;		-- id родителя 
	lv_p		integer;	-- уровень родителя
	count_childs_p	integer;	-- количество детей родителя
BEGIN
	-- для создания нового элемента достаточно заполнить  у него поле parent
	id_p := NEW.parent_id;

	ch := const_ch();
	lv := const_lv();

	-- найдем родителя
	SELECT lvl, count_childs INTO lv_p, count_childs_p FROM board_group WHERE board_group.id=id_p;	
	
	IF NOT FOUND THEN
		lv_p:=0; count_childs_p:=0;
		NEW.lvl := 0;
	ELSE
		-- Проверка 1: может ли родитель еше иметь детей
		IF count_childs_p >= ch THEN
			RAISE EXCEPTION 'Родителю c id=% более нельзя иметь детей (их количество уже %)', id_p, ch;
		END IF;

		-- Проверка 2: может ли родитель иметь детей
		IF lv_p = lv THEN
			RAISE EXCEPTION 'Элементу с id=% нельзя иметь детей (его уровень % максимально возможный)', id_p, lv;
		END IF;

		NEW.id := ((power((ch+1),(lv-lv_p-1)))*(count_childs_p+1))::bigint+id_p;
		NEW.lvl := lv_p + 1;		
	END IF;
	NEW.count_childs := 0;
	

	NEW.nm := NEW.id; -- ЭТО ТОЛЬКО ДЛЯ ТЕСТОВ, затем убрать
	RAISE NOTICE '	%', NEW;
	
	UPDATE board_group SET count_childs = count_childs_p+1 WHERE board_group.id = id_p;
	
	return NEW;
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION new_id_board()
  OWNER TO postgres;



- это не ревизия а просто заплатки на лету, не вдумываясь. пока такие мелочи в рефлексы не забьёте -- к здоровым людям с вопросами не приставайте. не поймутс.


бесконечно лень вчитываться в вашу пену слов и кода, т.ч. предположу, что вас, возможно , спас бы перенос AFTER DELETE логики в заключение в BEFORE DELETE [могу врать, но есть подозрение, что это так]

т.е.
Код: 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.
-- заглушка ----------
CREATE OR REPLACE FUNCTION del_id_board_after()
  RETURNS trigger AS
$BODY$DECLARE

	old_p_id	bigint;
	old_p_lv	integer;
	old_p_ch	integer;
	i		integer;

BEGIN
/*	
	-- возьмем Родителя удаленного Элемента
	SELECT id, lvl, count_childs 
		INTO old_p_id, old_p_lv, old_p_ch 
		FROM board_group 
	WHERE id=OLD.parent_id;	

	

	IF (old_p_ch > 0) THEN
		--- RAISE EXCEPTION 'old_p_id=%, old_p_lv=%, old_p_ch=%, OLD.id=%',old_p_id, old_p_lv, old_p_ch, OLD.id;
		i := fill_emp(old_p_id, old_p_lv, old_p_ch+1, OLD.id);
	END IF;
*/	
	RETURN NULL;
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION del_id_board_after()
  OWNER TO postgres;
--------------------------------------------------------
CREATE OR REPLACE FUNCTION del_id_board_before()
  RETURNS trigger AS
$BODY$DECLARE

	old_p_id	bigint;
	old_p_lv	integer;
	old_p_ch	integer;
	i		integer;

BEGIN
	IF OLD.count_childs > 0 THEN
		RAISE EXCEPTION 'У данного элемента имеются дети в количестве % шт. Удалите сначала их.', OLD.count_childs;
	END IF;

	-- возьмем Родителя удаленного Элемента
	SELECT id, lvl, count_childs 
		INTO old_p_id, old_p_lv, old_p_ch 
		FROM board_group 
	WHERE id=OLD.parent_id;	

	-- уменьшим количество детей у родителя
	UPDATE board_group SET count_childs = count_childs-1 WHERE id = OLD.parent_id;
	-----------------	-----------------
		IF (old_p_ch > 0) THEN
			--- RAISE EXCEPTION 'old_p_id=%, old_p_lv=%, old_p_ch=%, OLD.id=%',old_p_id, old_p_lv, old_p_ch, OLD.id;
			i := fill_emp(old_p_id, old_p_lv, old_p_ch+1, OLD.id);
		END IF;
	-----------------	-----------------	

	
	RETURN OLD;
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION del_id_board_before()
  OWNER TO postgres;



-- если я вру -- поправьте, желательно на пальцах.
(там реально думать надо [о видимостях и т.п.], а это затратно, а повода нет)


теперь -- почему нет повода:
id дерева -- это, как правило, ссылка на сущность, на которую ссылаются другие объекты (а не только оно само -- уробороссом) . каскадный апдейт всей базы, это то, за что не увольняют, а закапывают на месте. даже в блокировочнике. в случае версионника -- это еще и дублирование занятого дискового, и последующая глобальная сборка мусора [в postgresql -- воркерами автовакуума]

повторяю, в этом случае вам не помогать нужно, а вязать вас санитарами, пхать в смирительную, и на процедурки

так что, чтобы повысить юзабельность вашего макетика (который у вас рассыпается) сделайте отдельно -- board_id суррогат, неизменый. -- На него будете ссылаться снаружи, без всех этих каскадов. Вместо id и parent_id я бы ввел key и parent_key -- для читаемости, но это вопрос предпочтений и наличного кода.
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38885982
EvgIq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
сизиф и мартышки,

То, что вы сломя голову, не читая и не вникая бросились улучшать мир, давать советы, ставит под сомнение их ценность, а ваш тон и манеры - вашу адекватность.
Повторю для дурачков - я извинился за свой код (5-е сообщение в ветке). И вообще тема вопроса была другая. Но человек попросил, я запилил. Конечно все еще будет правиться/рефакториться/теститься и проч.
Про RETURN'ы - будет вызов констант из таблицы, так как в БД будет не одно дерево. Так что ваш совет очередной пук в лужу.
Про AFTER DELETE и BEFORE DELETE - так же писал уже, второй раз не вижу смысла так как см. первое предложение в этой мессаге.
и т.д. и т.п.
...вобщем для вас всё печально...
Но вы ведь здесь заняты тренировкой своего хилого больного остроумия, вместо обычного решения технических задач, что, несомненно, более пошло бы вам на пользу.
"Собака лает, караван идет", так вот, вы в этой ветке не караван. Не утруждайтесь далее, отдохните.
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38885997
EvgIqсизиф и мартышки,

То, что вы сломя голову, не читая и не вникая бросились улучшать мир, давать советы, ставит под сомнение их ценность, а ваш тон и манеры - вашу адекватность.
Повторю для дурачков - я извинился за свой код (5-е сообщение в ветке). И вообще тема вопроса была другая. Но человек попросил, я запилил. Конечно все еще будет правиться/рефакториться/теститься и проч.
Про RETURN'ы - будет вызов констант из таблицы, так как в БД будет не одно дерево. Так что ваш совет очередной пук в лужу.
Про AFTER DELETE и BEFORE DELETE - так же писал уже, второй раз не вижу смысла так как см. первое предложение в этой мессаге.
<>чотаржу.

select-ы вполне выполняются из таблиц
[это на предмет газификации луж return-ами]
смысл же изложен егоровым [выбор процедурного языка, прозрачного планировщику, а не синтаксиса]
повторяться не буду -- rtfm , и воздастся.

первое ваше сообщение (единственное о вашем предпочтении в выборе before -- after логики) я тоже бегло просмотрел -- т.ч. не обнаружил за вами внятного понимания, что вы делаете before, а что -- after. настаивать на прояснением этого не буду -- очевидно это непосильный для вас труд.


если караван до сих пор так и ходит -- только под себя , -- то это проблема корована.
и да, простите за издевательство -- старая зобава -- грабить корованы
как вижу -- "корован" -- так и тянет
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38886002
EvgIq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
сизиф и мартышки,
сабака грабит караваны?, что-то новенькое :) идите, работайте, повышайте тех уровень и недостающее воспитание, а то уволят ведь несмотря на высокие мотивы и каскадные операции.
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38886014
EvgIqсизиф и мартышки,
сабака грабит караваны?, что-то новенькое :) идите, работайте, повышайте тех уровень и недостающее воспитание, а то уволят ведь несмотря на высокие мотивы и каскадные операции.
деточка, заплесневелые мемы можно было бы и узнавать без расшифровки

ну или если в гугле не зобанеле -- то проявить реакцыю (быстрость разумом невтонов, ага)

а то же -- ни реакции, ни способности к педантичному труду
-- одни жениальные потуги, не подтверждённые ничем, кроме готовности пусто, кхм, лаяться

иди, куй, мальчик. вычёркиваю(тм).
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38886019
EvgIq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
сизиф и мартышки,
что за мем? неужели мартышки грабят караваны? гуголь так говорит? врет! :)
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38886266
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EvgIq,

Я попытался еще раз:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
ALTER TABLE board_group DISABLE TRIGGER before_new_id;
insert into board_group(id,lvl,count_childs,nm,parent_id) values (-128,0,0,0,-128);
ALTER TABLE board_group ENABLE TRIGGER before_new_id;

SELECT * FROM board_group;
INSERT INTO board_group(parent_id) values (-128);

ERROR:  null value in column "id" violates not-null constraint
DETAIL:  Failing row contains (null, null, null, null, -128).


Я бы рекомендовал привести код в порядок, т.к. передергивание триггеров требует эксклюзивного блока на таблицу. Заниматься этим каждый раз, когда необходимо создать новое дерево выглядит крайне неудобно.

Также я в третий раз прошу — предоставьте набор SQL-команд, которые приведут систему к виду, показанному вами на скриншотах.
На данный момент я сомневаюсь, что это возможно без грубой доделки молотком и зубилом.
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38886302
EvgIq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,
команда
Код: plsql
1.
INSERT INTO board_group values (0,0,0,0,-128);


Создаст элемент (-64,1,0,'-64',128)
затем
Код: plsql
1.
INSERT INTO board_group values (0,0,0,0,-128);


Создаст элемент (0,1,0,'0',128)
затем
Код: plsql
1.
INSERT INTO board_group values (0,0,0,0,-128);


Создаст элемент (64,1,0,'64',128)
ну и далее по аналогии
Код: plsql
1.
2.
3.
4.
5.
6.
INSERT INTO board_group values (0,0,0,0,64);
INSERT INTO board_group values (0,0,0,0,64);
INSERT INTO board_group values (0,0,0,0,64);
INSERT INTO board_group values (0,0,0,0,112);
INSERT INTO board_group values (0,0,0,0,112);
INSERT INTO board_group values (0,0,0,0,112);



Получится дерево как на картинке.
Я не зря приводил скрины из админки Django, чтобы было понятно что проект рабочий.
Вчера я переделал алгоритм - теперь, если получается "дырка", "складываю" ее родителя и номер в отдельную таблицу, и "забираю" ее оттуда при создании нового ребенка или перемещение к Родителю. Первоначальный вопрос, который в теме ветки, стал неактуален.
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38886315
EvgIq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В строках "создаст элемент" минус у родителя забыл указать... правильно так:
Создаст элемент (-64,1,0,'-64',-128)....Создаст элемент (0,1,0,'0',-128)....Создаст элемент (64,1,0,'64',-128)...
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38886768
vyegorov,

не мучайте дитё
оно в первый раз дорвалось до "одминки джанго"

и да, человечество придумало позиционную запись для экономии собственной памяти,
а оно возвращается от позиционной записи обратно к бесконечно длинным битовым словам
вместо записи слов длины M в алфавите N используя слова алфавита [01] длиной N^M
в общем -- алгоритмически там всё безобразно.
т.е. буквально всё, а не только подмеченное сибиряковым
т.ч. пусть себе играет в куличики, пока оно не лепит их у вас, в вашей команде
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38886793
EvgIq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
сизиф и мартышки,
О, грабитель караванов, компы раздали? :) Вы же вроде как разобиделись и попрощались? Правильно, не обижайтесь, заходите почаще, я завсегда рад подбодрить больного человека.
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38888366
Мутуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
EvgIq,

первый вопрос - да, верно
Код: 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.
create table tmp_test_del
(
  id integer,
  val integer
);



truncate table tmp_test_del;
insert into tmp_test_del
select i, i % 2  from generate_series(1, 10) as i;


--select * from tmp_test_del



CREATE OR REPLACE FUNCTION trf_tmp_test_del_bd()
  RETURNS trigger AS
$BODY$
BEGIN 
  raise notice 'BEFORE DELETE (id=%, rows=%)', OLD.id, (SELECT count(*) from tmp_test_del);
  RETURN OLD;  
END;
$BODY$
  LANGUAGE plpgsql VOLATILE SECURITY DEFINER  COST 100;
GRANT EXECUTE ON FUNCTION trf_tmp_test_del_bd() TO public;

CREATE TRIGGER tr_tmp_test_del_bd
  BEFORE DELETE
  ON tmp_test_del
  FOR EACH ROW
  EXECUTE PROCEDURE trf_tmp_test_del_bd();


CREATE OR REPLACE FUNCTION trf_tmp_test_del_ad()
  RETURNS trigger AS
$BODY$
BEGIN 
  raise notice 'AFTER DELETE (id=%, rows=%)', OLD.id, (SELECT count(*) from tmp_test_del);
  RETURN OLD;  
END;
$BODY$
  LANGUAGE plpgsql VOLATILE SECURITY DEFINER  COST 100;
GRANT EXECUTE ON FUNCTION trf_tmp_test_del_ad() TO public;

CREATE TRIGGER tr_tmp_test_del_ad
  AFTER DELETE
  ON tmp_test_del
  FOR EACH ROW
  EXECUTE PROCEDURE trf_tmp_test_del_ad();


--тест
delete from  tmp_test_del where val = 0


вывод:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
NOTICE:  BEFORE DELETE (id=2, rows=10)
NOTICE:  BEFORE DELETE (id=4, rows=9)
NOTICE:  BEFORE DELETE (id=6, rows=8)
NOTICE:  BEFORE DELETE (id=8, rows=7)
NOTICE:  BEFORE DELETE (id=10, rows=6)
NOTICE:  AFTER DELETE (id=2, rows=5)
NOTICE:  AFTER DELETE (id=4, rows=5)
NOTICE:  AFTER DELETE (id=6, rows=5)
NOTICE:  AFTER DELETE (id=8, rows=5)
NOTICE:  AFTER DELETE (id=10, rows=5)

Второй вопрос-
ну напишите свою функцию на удаление:
Код: sql
1.
2.
3.
4.
5.
6.
FUNCTION del(p_id integer)
$$
  -- do something
  delete from table where id = p_id;
  -- do something
$$



Третий вопрос-
www.pgadmin.org/docs/1.8/debugger.html
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38888372
Мутуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
подчищаем за собой

Код: sql
1.
2.
3.
4.
5.
DROP TRIGGER tr_tmp_test_del_ad ON tmp_test_del;
DROP TRIGGER tr_tmp_test_del_bd ON tmp_test_del;
DROP FUNCTION trf_tmp_test_del_bd();
DROP FUNCTION trf_tmp_test_del_ad();
DROP TABLE tmp_test_del;
...
Рейтинг: 0 / 0
Триггер DELETE в случае группового удаления данных
    #38888506
EvgIq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мутуз,
Спасибо, все понял.
...
Рейтинг: 0 / 0
17 сообщений из 42, страница 2 из 2
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Триггер DELETE в случае группового удаления данных
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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