Триггер вставки Postgresql для установки значения
Предположим, что в Postgresql есть таблица T
, а один из ее столбцов - C1
.
Я хочу вызвать функцию, когда новая запись добавляется в таблицу T
. Функция должна проверять значение столбца C1
в новой записи, а если оно равно null/empty, то установите значение 'X'
.
Возможно ли это?
Ответы
Ответ 1
Вы правы, что вам нужен триггер, потому что установка значения по умолчанию для столбца не будет работать для вас - значения по умолчанию работают только для значений null
и не помогают предотвратить пустые значения.
В postgres есть несколько шагов для создания триггера:
Шаг 1. Создайте функцию, которая возвращает тип trigger
:
CREATE FUNCTION my_trigger_function()
RETURNS trigger AS '
BEGIN
IF NEW.C1 IS NULL OR NEW.C1 = '''' THEN
NEW.C1 := ''X'';
END IF;
RETURN NEW;
END' LANGUAGE 'plpgsql'
Шаг 2. Создайте триггер, который запускается перед вставкой, что позволяет вам изменять значения, которые они вставили, что вызывает указанную выше функцию:
CREATE TRIGGER my_trigger
BEFORE INSERT ON T
FOR EACH ROW
EXECUTE PROCEDURE my_trigger_function()
И все готово.
Смотрите приведенный выше код на SQLFIddle, демонстрируя, что он работает правильно!
Вы отмечаете в комментарии, что значение 'X'
извлекается из подзапроса. Если это так, измените соответствующую строку так, чтобы:
NEW.C1 := (select some_column from some_table where some_condition);
Ответ 2
Возможно, но вы, скорее всего, будете лучше устанавливать ограничение по умолчанию для столбца. При создании таблицы, которая будет выглядеть так:
create table mytable as (
C1 thetype not null default X
);
Это говорит о том, что если вы добавите строку в таблицу и не укажете значение для C1, тогда вместо этого будет использоваться X. Нулевое значение необязательно, но не позволяет обновлениям обнулять этот столбец, предполагая, что вы хотите.
EDIT: Это работает только для постоянного X, из ваших комментариев кажется, что есть два возможных решения.
Использование триггера будет выглядеть примерно так:
create function update_row_trigger() returns trigger as $$
begin
if new.C1 is NULL then
new.C1 := X;
end if;
return new;
end
$$ language plpgsql;
create trigger mytrigger before insert on mytable for each row execute procedure update_row_trigger();
Переменная new
в триггерной функции является специальной, представляющей вставляемую строку. Указание триггера как триггера before insert
означает, что вы можете изменить строку до ее записи в таблицу.
Второе решение - использовать вычисляемый столбец, который Postgres определяет необычным образом:
create or replace function C1(row mytable) returns columntype immutable as $$
begin
return X; -- where X is an expression using values from `row`
end
$$ language plpgsql;
Это создает функцию, которая берет строку вашей таблицы и возвращает значение, вы можете вызвать ее с помощью. но обозначение, которое вы можете сделать:
select
*,
t.C1
from
mytable t;
Объявление неизменяемой функции необязательно, но это необходимо, если вы хотите индексировать "столбец". Вы можете индексировать этот столбец следующим образом:
create index on mytable (C1(mytable));