2016-03-09 4 views
1

Я создал небольшую функцию и небольшой триггер. Когда я запускаю простейший запрос DELETE, я вижу только уведомление и контекстное сообщение в консоли (никаких предупреждений и сообщений об ошибках), но этот запрос DELETE не имеет никакого эффекта (запись остается в таблице и не удаляется). Функция и триггер выглядеть следующим образом:Невозможно удалить строку в Postgresql

CREATE FUNCTION trigger_layers_before_del() RETURNS trigger 
AS $$ 
DECLARE 
    table_name text := (SELECT concat ('layer_', OLD.id::text, '_')); 
BEGIN 
    EXECUTE ' 
     DROP TABLE IF EXISTS ' || quote_ident(table_name) || ' CASCADE 
    '; 
    RETURN NULL; 
END; 
$$ LANGUAGE plpgsql; 

CREATE TRIGGER tr_layers_del_befor 
BEFORE DELETE ON layers FOR EACH ROW 
EXECUTE PROCEDURE trigger_layers_before_del(); 

И это, как DELETE команда выглядит следующим образом:

DELETE FROM layers where id = 31 

Так что, если я бегу:

DELETE FROM layers WHERE id = 31; 
SELECT * FROM layers WHERE id = 31; 

затем возвращает запись с id = 31 ,

В уведомлении говорится, что «таблица« layer_31_ »не существует, пропускает ...». Контекстное сообщение просто печатает заявление EXECUTE. Итак, если ошибок нет, почему команда DELETE не совершена?

ответ

3

Это потому, что ваша функция возвращает NULL. Согласно documentation:

триггерные функции, на которые ссылается в-ряд триггеров может возвращать строку таблицы (значение типа HeapTuple) вызывающему исполнителю, если они выбирают. Триггер на уровне строк вызывается перед операцией имеет следующие варианты:

  • Он может возвращать NULL, чтобы пропустить эту операцию для текущей строки. Это дает указание исполнителю не выполнять операцию на уровне строки, которая вызывала триггер (вставка, модификация или удаление строки таблицы ): .

  • для вставки на уровне строк и UPDATE триггера только, возвращенные строки становится строкой, которая будет вставлена ​​или заменит строку будучи обновляются. Это позволяет триггерной функции изменять строку, содержащую или обновляемую .

Строка уровень ДО триггера, который не намерен вызывать либо из такого поведения должна быть осторожными, чтобы вернуться в качестве результата тот же ряд , который был принят в (то есть, новой строке для вставки и UPDATE триггеры, OLD-строка для триггеров DELETE).

Итак, что вам нужно, это RETURN OLD;

+0

Спасибо! Оно работает! – Jacobian

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