Добавление чеков в таблицу postgres, где данные уже неверны - PullRequest
1 голос
/ 17 июня 2020

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

Если я изменю таблицу postgres, чтобы добавить проверку, но данные, которые уже есть, несовместимы с этой проверкой, с ней ничего не произойдет, верно? Postgres будет проверять только те данные, которые вставлены / обновлены после добавления проверки?

Предположим, что в какой-то строке в столбце «Год рождения» указано значение 1987. Что, если я добавлю проверку как «Год рождения> 1990», а я этого не сделаю обновлять это поле когда-либо, но я обновляю другое поле в этой строке. Смогу ли я обновить эту строку? Если нет, то есть ли способ добавить проверку таким образом, чтобы я мог обновлять все старые строки без проверки, но новые добавленные строки выполняются, в основном добавляя проверку только на запросы вставки, а не на запросы обновления ? Надеюсь, мой вопрос ясен для понимания.

Ответы [ 2 ]

2 голосов
/ 17 июня 2020

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

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

CREATE FUNCTION check_birthyear
                ()
                RETURNS TRIGGER
AS
$$
BEGIN
  IF NOT new.birthyear > 1990 THEN
    RAISE EXCEPTION 'birthyear must be greater than 1990';
  END IF;

  RETURN new;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER elbat_check_birthyear
               BEFORE INSERT
               ON elbat
               FOR EACH ROW
               EXECUTE PROCEDURE check_birthyear();

db <> fiddle

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

0 голосов
/ 17 июня 2020

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

Как было объяснено в другом ответе, существующие строки проверяется на допустимость, если вы создаете ограничение.

Есть одно исключение, которое позволит вам создать ограничение CHECK для таблицы, содержащей строки, нарушающие условие: создайте ограничение как NOT VALID. Тогда существующие строки не будут проверяться на соответствие.

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

Альтернатива Идея заключалась бы в том, чтобы добавить новый столбец old типа boolean, чтобы отличать guish старые строки от новых. Затем вы можете явно исключить старые строки из условия проверки.

...