Подтвердить что ты не робот

Триггер вставки Postgresql для установки значения

Предположим, что в Postgresql есть таблица T, а один из ее столбцов - C1.

Я хочу вызвать функцию, когда новая запись добавляется в таблицу T. Функция должна проверять значение столбца C1 в новой записи, а если оно равно null/empty, то установите значение 'X'.

Возможно ли это?

4b9b3361

Ответ 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));