Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Не выполняются DELETE внутри хранимой процедуры / 8 сообщений из 8, страница 1 из 1
01.02.2019, 16:18
    #39768313
sealse
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не выполняются DELETE внутри хранимой процедуры
Есть ХП рекурсивня, удаляет записи по FK ключам (так как CASCADE не прописанно)
Проблема. Отрабатывает правильно, но само удаление не происходит. Как я понимаю рекурсивня процедура не выполняет сохранение делитов и как следствие останавливается из-за не возможности удалить по FK строки, связь которая должна был быть уже уддалена.
Как правильно знакомитить транзакцию вызванной процедуры, если COMMIT не работает?
...
Рейтинг: 0 / 0
04.02.2019, 12:11
    #39769140
Hawkmoon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не выполняются DELETE внутри хранимой процедуры
sealse,

1) почему нельзя сделать cascade?
2) перейти на PG 11, в котором есть хранимые ПРОЦЕДУРЫ и возможность их коммитить.
...
Рейтинг: 0 / 0
04.02.2019, 12:17
    #39769151
Melkij
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не выполняются DELETE внутри хранимой процедуры
Hawkmoon2) перейти на PG 11, в котором есть хранимые ПРОЦЕДУРЫ и возможность их коммитить.
И чем это поможет?
Если автор не может реализовать каскад в транзакции - ровно та же проблема будет в нескольких транзакциях.
Каскадные FK работают? А это банальные запросы через SPI интерфейс базы.

sealseОтрабатывает правильно, но само удаление не происходит.
Отлаживайте.
Вы не показали ничего из своей попытки реализации.
...
Рейтинг: 0 / 0
04.02.2019, 12:49
    #39769169
Hawkmoon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не выполняются DELETE внутри хранимой процедуры
MelkijИ чем это поможет?
1)Автор пожаловался на невозможность закоммитить результат рекурсии перед очередным вызовом рекурсии.
Жалоба неприменима для версии старше 11. Это безотносительно данной проблемы.

2)И может быть, версию СУБД покажет.
...
Рейтинг: 0 / 0
04.02.2019, 16:02
    #39769298
sealse
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не выполняются DELETE внутри хранимой процедуры
автор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);
...
Рейтинг: 0 / 0
04.02.2019, 17:25
    #39769336
Hawkmoon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не выполняются DELETE внутри хранимой процедуры
sealse,

Блин, самописный constraint "по соображениям безопасности". А почему в базе, а не на php?

"нервным не смотреть"Дайте угадаю, а индексирование для быстрого поиска данных - на стороне php?
Потому что я реально это видел, но только в жава-клиенте. Чувак сам писал себе что-то типа B-tree.
...
Рейтинг: 0 / 0
06.02.2019, 14:50
    #39770180
sealse
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не выполняются DELETE внутри хранимой процедуры
Hawkmoon,

Да Дактрина как Хибернейт в Джава - строит сама структуру БД из Энтити

авторБлин, самописный constraint "по соображениям безопасности". А почему в базе, а не на php?

Изначально казалось дольше да и сейчас не уверен что скрипт будет быстрее написать. В результате вывело 156 Делитов для удаления одного клиента.
Да, кстати, скрипт с примера выше не работал потому что не было цикла по дочерней таблице если там записей больше одной. А не по причине не закрытой транзакции.
НО я позже столкнулся как не смешно с той же проблемой транзакции но по другому. И Именно:
Скрипт нашел таблицы в которых FK перекрестные. И удалить записи с них вообще нельзя не удалив один из FK
Первая мысль грохнуть один из них и вот тут словил
"cannot ALTER TABLE "..." because it is being used by active queries in this session"
Т.е. все равно уперся в проблему завершения сессии процедуры и закрытии ее транзакции.

Саму проблему я решил, выведя в консоль строкой все нужные Алерты и Делиты. Запустив Алерты в ручную самим же скриптом потом даже все и удалил. Но остался червячек с тем что не остался скриптец который делает все сам. :)
...
Рейтинг: 0 / 0
07.02.2019, 09:43
    #39770515
Ivan Durak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не выполняются DELETE внутри хранимой процедуры
потом догадаешься что проще не удалять сразу, а помечать на удаление,
а удалять в фоновом режиме, отдельными заданиями и все сразу.
Изобретешь свой вакуум, так сказать.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Не выполняются DELETE внутри хранимой процедуры / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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