2017-01-12 3 views
0

Я пытаюсь вызвать функцию из триггерной функции и не понимаю, какую структуру управления использовать. Вот ситуация: У меня есть 3 таблицы (table1, table2, table3) и две функции (Fct1 и Fct2).
Fct1 функция триггера запускается после вставки в table1 и что делает вставку в table2:postgresql встроенная функция return

CREATE OR REPLACE FUNCTION Fct1() 
    RETURNS TRIGGER AS 
$BODY$ 

BEGIN 

TRUNCATE "table2"; 
INSERT INTO "table2" 
SELECT ... FROM "table1"; 

RETURN NEW; 

END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 

Триггер:

CREATE TRIGGER trig_fct1 
    AFTER INSERT 
    ON table1 
    FOR EACH ROW 
    WHEN ((pg_trigger_depth() < 1)) 
    EXECUTE PROCEDURE Fct1(); 

Если я после этого SELECT "Fct2"(); все работает отлично, но если добавить в Fct1 PERFORM "Fct2"();, как это:

CREATE OR REPLACE FUNCTION Fct1() 
    RETURNS TRIGGER AS 
$BODY$ 

BEGIN 

TRUNCATE "table2"; 
INSERT INTO "table2" 
SELECT ... FROM "table1"; 

TRUNCATE "table3"; 
PERFORM "Fct2"(); -- will insert into table3 

RETURN NEW; 

END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 

это занимает гораздо больше времени, чтобы работать (я никогда не ждать ed для конца, он слишком длинный).
Fct2 выглядит следующим образом

CREATE OR REPLACE FUNCTION "Fct2"() 
    RETURNS void AS 
$BODY$ 

BEGIN 

INSERT INTO "table3" ...; 

RETURN; 

END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 

Итак, есть что-то я не понимаю, и я думаю, что это связано с этими «ВОЗВРАЩАЕТСЯ», которые не являются для меня ясно. Я пробовал разные «решения», но у меня всегда были ошибки, упоминающие некоторые «обратные» несоответствия. Какие-либо предложения ?

Я использую PostgreSQL 9.6

+0

Пожалуйста, отредактируйте ваш вопрос и добавьте оператор 'create trigger', который вы использовали (это триггер уровня или триггер уровня инструкции)? –

+0

Добавлен оператор создания триггера. –

+0

Наконец, я переписал свою функцию и сменил триггер на «Для каждого утверждения», который был правильным путем. Помимо того факта, что мой код был очень плохо написан (быстрый и грязный), существовал какой-то цикл из-за «для каждой строки», а время обработки было экспоненциальным с количеством строк. –

ответ

0

Чтобы захватить долго выполняющиеся операторы SQL из функций в журнале, вы можете использовать auto_explain с auto_explain.log_nested_statements набором для on. Но если запрос не заканчивается, это не поможет.

Моя ставка заключается в том, что вы заблокированы блокировкой базы данных. Установите log_lock_waits на номер on и посмотрите, не сообщается ли что-либо в журнале. Вы также должны запросить pg_locks, чтобы узнать, есть ли запрошенные блокировки, но не предоставлены.

+0

Спасибо Laurenz за то, что нашли время, чтобы ответить. Наконец, я полностью переписал свою функцию и триггер, и теперь он работает очень спокойно. –

Смежные вопросы