|
Не выполняются DELETE внутри хранимой процедуры
|
|||
---|---|---|---|
#18+
Есть ХП рекурсивня, удаляет записи по FK ключам (так как CASCADE не прописанно) Проблема. Отрабатывает правильно, но само удаление не происходит. Как я понимаю рекурсивня процедура не выполняет сохранение делитов и как следствие останавливается из-за не возможности удалить по FK строки, связь которая должна был быть уже уддалена. Как правильно знакомитить транзакцию вызванной процедуры, если COMMIT не работает? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.02.2019, 16:18 |
|
Не выполняются DELETE внутри хранимой процедуры
|
|||
---|---|---|---|
#18+
sealse, 1) почему нельзя сделать cascade? 2) перейти на PG 11, в котором есть хранимые ПРОЦЕДУРЫ и возможность их коммитить. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.02.2019, 12:11 |
|
Не выполняются DELETE внутри хранимой процедуры
|
|||
---|---|---|---|
#18+
Hawkmoon2) перейти на PG 11, в котором есть хранимые ПРОЦЕДУРЫ и возможность их коммитить. И чем это поможет? Если автор не может реализовать каскад в транзакции - ровно та же проблема будет в нескольких транзакциях. Каскадные FK работают? А это банальные запросы через SPI интерфейс базы. sealseОтрабатывает правильно, но само удаление не происходит. Отлаживайте. Вы не показали ничего из своей попытки реализации. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.02.2019, 12:17 |
|
Не выполняются DELETE внутри хранимой процедуры
|
|||
---|---|---|---|
#18+
MelkijИ чем это поможет? 1)Автор пожаловался на невозможность закоммитить результат рекурсии перед очередным вызовом рекурсии. Жалоба неприменима для версии старше 11. Это безотносительно данной проблемы. 2)И может быть, версию СУБД покажет. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.02.2019, 12:49 |
|
Не выполняются DELETE внутри хранимой процедуры
|
|||
---|---|---|---|
#18+
автор1) почему нельзя сделать cascade? Так исторически сложилось якобы для безопастности БД. cascade не прописана и прописывать ее не дадут (к слову речь о пхп+доктрина) автор2) перейти на PG 11, в котором есть хранимые ПРОЦЕДУРЫ и возможность их коммитить. Только на 10-й перешли. Надо бы что бы работало на PG 9.6 и 10 авторОтлаживайте. Вы не показали ничего из своей попытки реализации. CREATE OR REPLACE FUNCTION select_fk( search_table varchar(30), name_id varchar(30), id int ) RETURNS SETOF boolean AS $$ DECLARE s_record record; e_sql text; c_sql text; s_sql text; name_seq text; delete_sql text; count_tables int; sub_id INT; integer_var INT; result boolean; BEGIN result = false; RAISE NOTICE '-- START table="%" name_id="%" id="%" --', search_table, name_id, id; CREATE temporary table IF NOT EXISTS tmp_tables(table_name varchar(255)) on commit drop; FOR s_record IN SELECT tc.table_schema AS foreign_table_schema, tc.constraint_name, tc.table_name AS foreign_table_name, kcu.column_name AS foreign_column_name, ccu.table_schema AS table_schema, ccu.table_name, ccu.column_name FROM information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name AND ccu.table_schema = tc.table_schema WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name=search_table LOOP e_sql = format ('SELECT count(*) from tmp_tables WHERE table_name = %L', s_record.foreign_table_name ); -- RAISE NOTICE 'e_sql = %', e_sql; EXECUTE e_sql INTO count_tables; -- RAISE NOTICE 'count_tables = %', count_tables; IF count_tables > 0 THEN -- RAISE NOTICE ' ---! in array true --- '; ELSE -- RAISE NOTICE 'f_table_schema = %; f_table_name = % f_column_name = %', -- s_record.foreign_table_schema, -- s_record.foreign_table_name, -- s_record.foreign_column_name -- ; c_sql = format ('SELECT isc.column_name ' || 'FROM information_schema.sequences as iss, information_schema.columns as isc' || ' WHERE iss.sequence_name = %L ' || ' and isc.table_name = %L ' || ' and isc.column_default like %L', s_record.foreign_table_name || '_id_seq', s_record.foreign_table_name, '%' || s_record.foreign_table_name || '_id_seq%' ); -- RAISE NOTICE '-1 % -- ', c_sql; EXECUTE c_sql INTO name_seq; -- RAISE NOTICE 'seq = %', name_seq; IF name_seq IS NOT NULL THEN s_sql = format ('SELECT %I FROM %I WHERE %I = %s', name_seq, s_record.foreign_table_name, s_record.foreign_column_name, id ); -- RAISE NOTICE '-2 % -- ', s_sql; EXECUTE s_sql INTO sub_id; -- RAISE NOTICE '!! % !! ', sub_id; IF sub_id>0 THEN -- RAISE NOTICE '-- % -- table="%" column="%"', sub_id, s_record.table_name,s_record.foreign_column_name; INSERT INTO tmp_tables VALUES (s_record.foreign_table_name); EXECUTE format( 'SELECT select_fk(%L, %L, %s)', s_record.foreign_table_name, name_seq, sub_id) INTO result; ELSE delete_sql = format( 'DELETE FROM %I WHERE %I = %s;', s_record.foreign_table_name, s_record.foreign_column_name, id); RAISE NOTICE 'SUB delete_sql=%', delete_sql; EXECUTE format('LOCK TABLE %I IN EXCLUSIVE MODE' , s_record.foreign_table_name); BEGIN EXECUTE delete_sql; EXCEPTION WHEN unique_violation THEN RAISE NOTICE 'ERROR_sql=%', delete_sql; -- don't worry if it already exists END; GET DIAGNOSTICS integer_var = ROW_COUNT; RAISE NOTICE 'integer_var=%', integer_var; END IF; END IF; END IF; END LOOP; delete_sql = format( 'DELETE FROM %I WHERE %I = %s;', search_table, name_id, id); RAISE NOTICE 'PRM delete_sql=%', delete_sql; EXECUTE format('LOCK TABLE %I IN EXCLUSIVE MODE' , search_table); EXECUTE delete_sql; GET DIAGNOSTICS integer_var = ROW_COUNT; RAISE NOTICE 'integer_var=%', integer_var; RAISE NOTICE '-- END table="%" --', search_table; RETURN NEXT result; END $$ LANGUAGE plpgsql VOLATILE; select select_fk('erp_clients', 'id', 6579 ); DROP FUNCTION IF EXISTS select_fk(character varying,character varying,integer); ... |
|||
:
Нравится:
Не нравится:
|
|||
04.02.2019, 16:02 |
|
Не выполняются DELETE внутри хранимой процедуры
|
|||
---|---|---|---|
#18+
sealse, Блин, самописный constraint "по соображениям безопасности". А почему в базе, а не на php? "нервным не смотреть"Дайте угадаю, а индексирование для быстрого поиска данных - на стороне php? Потому что я реально это видел, но только в жава-клиенте. Чувак сам писал себе что-то типа B-tree. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.02.2019, 17:25 |
|
Не выполняются DELETE внутри хранимой процедуры
|
|||
---|---|---|---|
#18+
Hawkmoon, Да Дактрина как Хибернейт в Джава - строит сама структуру БД из Энтити авторБлин, самописный constraint "по соображениям безопасности". А почему в базе, а не на php? Изначально казалось дольше да и сейчас не уверен что скрипт будет быстрее написать. В результате вывело 156 Делитов для удаления одного клиента. Да, кстати, скрипт с примера выше не работал потому что не было цикла по дочерней таблице если там записей больше одной. А не по причине не закрытой транзакции. НО я позже столкнулся как не смешно с той же проблемой транзакции но по другому. И Именно: Скрипт нашел таблицы в которых FK перекрестные. И удалить записи с них вообще нельзя не удалив один из FK Первая мысль грохнуть один из них и вот тут словил "cannot ALTER TABLE "..." because it is being used by active queries in this session" Т.е. все равно уперся в проблему завершения сессии процедуры и закрытии ее транзакции. Саму проблему я решил, выведя в консоль строкой все нужные Алерты и Делиты. Запустив Алерты в ручную самим же скриптом потом даже все и удалил. Но остался червячек с тем что не остался скриптец который делает все сам. :) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.02.2019, 14:50 |
|
|
start [/forum/topic.php?fid=53&msg=39770180&tid=1995364]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
44ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
47ms |
get tp. blocked users: |
1ms |
others: | 263ms |
total: | 397ms |
0 / 0 |