Невозможно вставить данные, ошибка внешнего ключа на postgresql - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть 3 таблицы, где в таблице INTRUSIONS есть внешние ключи, принадлежащие таблицам CCTVS и ALARMS.Я хочу, чтобы внешние ключи обнулялись в моей таблице INTRUSIONS.Я не уверен, почему, но я не могу вставить данные в свою таблицу «INTRUSIONS».Вот мой код:

CREATE  TABLE
REMOTE_SECURITY.CCTVS(CCTV_ID   serial);

CREATE  TABLE
REMOTE_SECURITY.ALARMS(ALARM_ID serial);

CREATE  TABLE
REMOTE_SECURITY.INTRUSIONS(INTRUSION_ID serial,CCTV_ID  serial,ALARM_ID serial);

ALTER   TABLE
REMOTE_SECURITY.CCTVS   ADD CONSTRAINT
CCTVS_PK    PRIMARY KEY
(CCTV_ID)
;
ALTER   TABLE
REMOTE_SECURITY.ALARMS  ADD CONSTRAINT
ALARMS_PK   PRIMARY KEY
(ALARM_ID)
;

Этот код не работает:

  INSERT
    INTO
        REMOTE_SECURITY.INTRUSIONS
    (
        INTRUSION_ID
    ,   CCTV_ID
    ,   ALARM_ID
    ) VALUES (
        1
    ,   NULL
    ,   1
    )
    ;

Вот ошибка:

[2018-11-19 19:35:59] [23502] ERROR: null value in column "cctv_id" violates not-null constraint
[2018-11-19 19:35:59] Detail: Failing row contains (1, null, 1, 2010-02-01 07:00:01).

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Ваши Error понятны .. Вы не можете установить Null значение Foreign Key или Serial .. Возможно, вы ошибаетесь в концепции дизайна вашего schema ..

CREATE TABLE tablename (
    colname SERIAL
);

эквивалентно указанию:

CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
    colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

Как отметил Documentation Serial тип данных удерживает Not Null, поэтому он не может быть Null, а другой ответ действительно здорово расскажет о внешнем ключе ограничения ..

Как Documentation FK сказал

Мы говорим, что это поддерживает ссылочную целостность между двумя связанными Таблицы

Итак. Значение в FK относится к значению Parents, которое PK .. PK не может иметь Null, поэтому FK тоже ..

0 голосов
/ 21 ноября 2018

Столбец внешнего ключа (intrusions.cctv_id или intrusions.alarm_id в вашем случае) должен не быть определен как serial, так как вы не хотите генерировать новые значения каждый раз, когда вы вставляете в них.Вы используете сгенерированные значения из указанных столбцов первичного ключа

Как указал dwir182, столбец serial неявно определяется как not null.Исправив неправильное определение столбцов FK, вы сможете вставлять значения NULL.

Итак, вы хотите:

CREATE TABLE remote_security.intrusions
(
  intrusion_id   serial,
  -- no serial for the foreign key columns!
  cctv_id        integer references cctvs,
  alarm_id       integer references alarms
);

Тогда вы можете сделать следующее:

insert into remote_security.cctvs values (default); -- creates id = 1;
insert into remote_security.alarms values (default); -- creates id = 1;

-- do not specify a value for the serial column!
insert into remote_security.intrusions 
  (intrusion_id, cctv_id, alarm_id)
values 
  (default, null, 1);

См. Онлайн-пример: https://rextester.com/ELPHK12991

0 голосов
/ 20 ноября 2018

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

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

https://www.postgresql.org/docs/9.4/ddl-constraints.html

...