Интервалы: Как я могу убедиться, что в столбце timstamp в таблице есть только одна строка с нулевым значением? - PullRequest
7 голосов
/ 11 мая 2011

У меня есть таблица со столбцом, в котором содержится дата «Действителен до», и я хочу убедиться, что в одной строке таблицы она может быть установлена ​​только на ноль. Есть ли простой способ сделать это?

Моя таблица выглядит так (postgres):

CREATE TABLE 123.myTable(
some_id integer NOT NULL,
valid_from timestamp without time zone NOT NULL DEFAULT now(),
valid_until timestamp without time zone,
someString character varying)

some_id и valid_from - мой ПК. Я не хочу, чтобы никто вводил строку с нулевым значением в столбце valid_until, если для этого PK уже есть строка с нулевым значением.

Спасибо

Ответы [ 7 ]

2 голосов
/ 04 июня 2016

В PostgreSQL у вас есть два основных подхода:

  1. Используйте 'infinity' вместо нуля.Тогда ваше уникальное ограничение работает, как и ожидалось.Или, если вы не можете сделать это:
  2. CREATE UNIQUE INDEX null_valid_from ON mytable(someid) where valid_until IS NULL

Я использовал оба подхода.Обычно я нахожу, что первый подход более чистый, и он позволяет вам использовать типы диапазонов и лучше исключать ограничения в более новых версиях PostgreSQL (чтобы не допустить перекрытия двух временных диапазонов, основанных на данном заданном someid), но второй подход часто полезен, когдапервое не может быть сделано.

0 голосов
/ 11 мая 2011

Хорошо, если вы используете MS SQL, вы можете просто добавить уникальный индекс в этот столбец.Это позволит только один NULL.Я предполагаю, что если вы используете другие RDBMS, это все равно будет работать.

0 голосов
/ 11 мая 2011

Я бы предложил вставить в эту таблицу через SP и поместить туда свои ограничения, поскольку триггеры довольно скрыты и о них, вероятно, будут забыты. Если это не вариант, сработает следующий триггер:

CREATE TABLE dbo.TESTTRIGGER
(
    YourDate Date NULL
)


    CREATE TRIGGER DupNullDates
ON dbo.TESTTRIGGER
FOR INSERT, UPDATE
AS 
DECLARE @nullCount int
SELECT @nullCount = (SELECT COUNT(*) FROM TESTTRIGGER WHERE YourDate IS NULL)
IF(@NullCount > 1)
BEGIN
    RAISERROR('Cannot have Multiple Nulls', 16, 1)
    ROLLBACK TRAN
END

GO
0 голосов
/ 11 мая 2011

Я знаю только Oracle достаточно подробно, но то же самое может работать в других базах данных:

  1. создайте другой столбец, который всегда содержит фиксированное значение (скажем, «0»), включите этот столбец в свой уникальный ключ.

  2. Не используйте NULL, но определите очень высокое или низкое значение. Во многих случаях это на самом деле проще использовать, чем значение NULL

  3. Создание уникального ключа на основе функции для функции, преобразующей дату, включая нулевое значение, в некоторое другое значение (например, строковое представление для дат и «x» для нулевого)

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

    выбрать количество (*) cnt из таблицы, где valid_until равен NULL

может работать как оператор выбора. И проверочное ограничение, ограничивающее значение cnt значениями 0 и 1

0 голосов
/ 11 мая 2011

Я предполагаю, что вы храните записи с датами вступления в силу и также используете действительную дату.

Если это так, вы можете использовать хранимые процедуры CRUD для обеспечения соблюдения этого правила.Например, вставка закрывает все недействительные даты перед вставкой новой записи с нулевой действительной датой.

Вероятно, вам потребуется проверка других хранимых процедур, чтобы избежать наложения записей и разрешить удаление и редактирование записей.Может оказаться более эффективным (с точки зрения, где условия / более быстрые запросы) использовать дату в далеком будущем, а не ноль.

0 голосов
/ 11 мая 2011

Как сказал Кевин в своем ответе, вы можете настроить триггер базы данных, чтобы запретить кому-либо вставлять более одной строки, где допустимая дата до NULL.

Оператор SQL, который проверяет это условие:

SELECT COUNT(*)
FROM TABLE
WHERE valid until IS NULL; 

Если счетчик не равен 1, то у вашей таблицы есть проблема.

Процесс, которыйДобавление строки в эту таблицу должно выполнить следующее:

  • Найти строку, в которой действительное значение до составляет NULL
  • Обновить действительное значение до текущей даты, илинекоторая другая значимая дата
  • Вставьте новую строку с действительным до тех пор, пока значение не будет установлено на NULL
0 голосов
/ 11 мая 2011

В зависимости от базы данных у вас не может быть нулевого в первичном ключе (я не знаю обо всех базах данных, но на сервере sql вы не можете). Самый простой способ обойти это - установить минимальное значение для даты и времени, а затем добавить к нему уникальное ограничение или установить его в качестве первичного ключа.

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

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