Странное поведение последовательности postgres

#postgresql #stored-procedures #entity-framework-4 #sequence

#postgresql #хранимые процедуры #entity-framework-4 #последовательность

Вопрос:

У меня есть таблица базы данных Postgres 9.04 с таблицей в ней, называемой Версиями:

 CREATE TABLE tracking."Versions"
(
    "ObjectId"      UUID            NOT NULL,
    "From"          BIGINT          NOT NULL,
    "To"            BIGINT,
    "DataTypeId"    INTEGER         NOT NULL REFERENCES tracking."DataTypes" ( "DataTypeId" ),
    CONSTRAINT "Versions_pkey" PRIMARY KEY ("ObjectId", "DataTypeId")
);
  

В базе данных также определена последовательность, которая используется столбцами From и To:

 CREATE SEQUENCE tracking."dbVersion"
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;
  

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

  • Когда строка создается в одной из этих других таблиц, строка добавляется в таблицу Versions, а столбец From должен быть установлен на следующее значение последовательности.
  • Если существующая строка в одной из этих таблиц обновляется, значение From соответствующей строки в таблице Versions должно быть установлено на следующее значение последовательности.
  • Когда строка в одной из этих других таблиц удаляется, в столбце To должно быть установлено следующее значение последовательности.

Вместо того, чтобы устанавливать значение по умолчанию для столбца From равным «nextval(‘tracking.’dbVersion’), я реализовал хранимую функцию, которая возвращает результат вызова этой функции:

 CREATE OR REPLACE FUNCTION tracking."NextVersion"() RETURNS BIGINT
AS $$
    SELECT nextval('tracking."dbVersion"'::regclass);
$$ LANGUAGE Sql;
  

Весь мой код для вставки строк в таблицы реализован на C # с использованием Entity Framework 4. Весь код C # работает нормально. Странно то, что когда я смотрю на данные в таблице Versions, значения в столбце From все четные. Когда я смотрю на свойства последовательности в pgAdmin, это странно. Но при следующей вставке строки сохраненное значение будет четным.

Что я делаю не так? Как Postgres всегда использует все значения, когда вы помещаете этот вызов nextval в свойство столбца по умолчанию?

Комментарии:

1. 1. Почему вы используете эту tracking.NextVersion() функцию вместо прямого вызова nextval()? Я не вижу никакого преимущества в использовании функции, которая вызывает только функцию. 2. Как вы присваиваете эти значения своему From столбцу?

2. Я использую Entity Framework. Я не знаю, как вызвать функцию непосредственно оттуда. Entity Framework может очень легко вызывать сохраненные функции, поэтому я обернул вызов в сохраненную функцию, чтобы я мог вызвать ее единственным известным мне способом на C #. Назначение также выполняется в C #: version. From = context.NextVersion();

3.Не видя вашего кода на C #, вероятно, невозможно понять, почему вы получаете только четные числа. НО … nextval() это функция, поэтому, если вы можете вызывать tracking.NextVersion() , вы должны быть в состоянии вызывать nextval() так же легко.

4. Однако я бы не стал использовать C # для присвоения вашего From значения столбца. Лучше сделать это с DEFAULT значением или триггером (если это необходимо как для обновлений, так и для вставок)

5. Также необходимо обновлять столбец TO при удалении. Выполнение этого в триггере имело бы смысл. Но мне нужно было бы написать триггер для каждой таблицы, которую мы отслеживаем. Это около дюжины триггеров. Невозможно отменить.

Ответ №1:

Что ж, пришло время мне почувствовать себя застенчивым.

Я просмотрел свой код на C # для вставки строк в таблицу Versions и обнаружил, что на самом деле я дважды вызывал хранимую процедуру NextVersion. Это объясняет, почему последовательность всегда была четной, когда она была записана в поле From . Я удалил второй вызов и проблема решена.

Тони