ПРОВЕРИТЬ (table1.integer> = table2.integer) - PullRequest
1 голос
/ 23 сентября 2019

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

Например, допустимы следующие таблицы:

=# SELECT * FROM table1;
 current_project_number
------------------------
                     12

=# SELECT * FROM table2;
 project_name | project_number
--------------+----------------
 Schaf        |              1
 Hase         |              8
 Hai          |             12

И следующие таблицы НЕ будут действительны:

=# SELECT * FROM table1;
 current_project_number
------------------------
                     12

=# SELECT * FROM table2;
 project_name | project_number
--------------+----------------
 Schaf        |              1
 Hase         |              8
 Hai          |             12
 Erdmännchen  |             71    <-error:table1.current_project_number is NOT >= 71

Обратите внимание, что это ограничение CHECK предназначено для того, чтобы гарантировать, что информация, подобная выше, не может быть вставлена.Я не смотрю на значения SELECT, где current_project_number> = project_number, речь идет о INSERTing

Что мне нужно для того, чтобы такой CHECK работал?Спасибо

1 Ответ

1 голос
/ 23 сентября 2019

Определение ограничения CHECK, которое ссылается на другую таблицу, возможно, но серьезно плохая идея, которая приведет к проблемам в будущем.

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

Другими словами, PostgreSQL не будет гарантировать, что ограничение всегда действует.Это может и приведет к неприятным сюрпризам, например, к резервной копии, взятой с pg_dump, которая больше не может быть восстановлена.

Не идите по этому пути.

Если вам нужна подобная функциональность, определите BEFORE INSERT триггер на table1, который проверяет условие и в противном случае выдает исключение:

CREATE FUNCTION ins_trig() RETURNS trigger
   LANGUAGE plpgsql AS
$$BEGIN
   IF EXISTS (SELECT 1 FROM table1
              WHERE NEW.project_number > current_project_number)
   THEN
      RAISE EXCEPTION 'project number must be less than or equal to values in table1';
   END IF;

   RETURN NEW;
END;$$;

CREATE TRIGGER ins_trig BEFORE INSERT ON table2
   FOR EACH ROW EXECUTE PROCEDURE ins_trig();
...