Вызов now () в функции - PullRequest
2 голосов
/ 08 июля 2011

Одна из наших таблиц Postgres, называемая rep_event, имеет столбец отметки времени, который указывает, когда была вставлена ​​каждая строка. Но все строки имеют значение временной метки 2000-01-01 00:00:00, поэтому что-то настроено неправильно.

Существует функция, которая вставляет строки в таблицу, и это единственный код, который вставляет строки в эту таблицу - никакой другой код не вставляет в эту таблицу. (Также нет кода, который обновляет строки в этой таблице.) Вот определение функции:

CREATE FUNCTION handle_event() RETURNS "trigger"
AS $$
BEGIN
    IF (TG_OP = 'DELETE') THEN
        INSERT INTO rep_event SELECT 'D', TG_RELNAME, OLD.object_id, now();
        RETURN OLD;
    ELSIF (TG_OP = 'UPDATE') THEN
        INSERT INTO rep_event SELECT 'U', TG_RELNAME, NEW.object_id, now();
        RETURN NEW;
    ELSIF (TG_OP = 'INSERT') THEN
        INSERT INTO rep_event SELECT 'I', TG_RELNAME, NEW.object_id, now();
        RETURN NEW;
    END IF;
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

Вот определение таблицы:

CREATE TABLE rep_event
(
operation character(1) NOT NULL,
table_name text NOT NULL,
object_id bigint NOT NULL,
time_stamp timestamp without time zone NOT NULL
)

Как видите, функция now () вызывается для получения текущего времени. Выполнение «select now ()» в базе данных возвращает правильное время, поэтому есть ли проблема с вызовом now () из функции?

Ответы [ 2 ]

4 голосов
/ 08 июля 2011

Более простое решение - просто изменить определение таблицы, чтобы значение NOW () было значением по умолчанию:

CREATE TABLE rep_event (
    operation character(1) NOT NULL,
    table_name text NOT NULL,
    object_id bigint NOT NULL,
    time_stamp timestamp without time zone NOT NULL DEFAULT NOW()
);

Затем вы можете избавиться от вызовов now () в вашем триггере.

Также в качестве примечания настоятельно рекомендую включить в вашу функцию порядок столбцов ... IOW;

INSERT INTO rep_event (operation,table_name,object_id,time_stamp) SELECT ...

Таким образом, если вы когда-нибудь добавите новый столбец или внесете другие изменения в таблице, которые изменятвнутреннее упорядочение таблиц, ваша функция не будет внезапно нарушена.

1 голос
/ 08 июля 2011

Ваша проблема должна быть в другом месте, так как ваша функция работает хорошо. Создайте тестовую базу данных, вставьте код, который вы цитировали, и запустите:

create table events (object_id bigserial, data text);
create trigger rep_event
  before insert or update or delete on events
  for each row execute procedure handle_event();

insert into events (data) values ('v1'),('v2'),('v3');
delete from events where data='v2';
update events set data='v4' where data='v3';

select * from events;
<i>     object_id | data 
    -----------+------
             1 | v1
             3 | v4
</i>
select * from rep_event;
<i>     operation | table_name | object_id |         time_stamp         
    -----------+------------+-----------+----------------------------
     I         | events     |         1 | 2011-07-08 10:31:50.489947
     I         | events     |         2 | 2011-07-08 10:31:50.489947
     I         | events     |         3 | 2011-07-08 10:31:50.489947
     D         | events     |         2 | 2011-07-08 10:32:12.65699
     U         | events     |         3 | 2011-07-08 10:32:33.662936
    (5 rows)
</i>

Проверьте другие триггеры, команду создания триггера и т. Д. И измените это timestamp without timezone на timestamp with timezone.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...