2016-10-05 2 views
1

у меня есть следующие таблицы:SQL оператор вставляет 2 строки вместо 1

CREATE TABLE public.configuration_parameter 
(
    id SERIAL, 
    type parameter_type NOT NULL, 
    CONSTRAINT configuration_parameter_pk PRIMARY KEY (id) 
); 

CREATE TABLE public.parameter_varchar 
(
-- Inherited from table configuration_parameter: id integer NOT NULL DEFAULT nextval('configuration_parameter_id_seq'::regclass), 
-- Inherited from table configuration_parameter: type parameter_type NOT NULL, 
    configuration_parameter_id integer NOT NULL, 
    name character varying NOT NULL, 
    is_required boolean NOT NULL, 
    default_value character varying, 
    max_length integer, 
    CONSTRAINT parameter_varchar_pk PRIMARY KEY (configuration_parameter_id), 
    CONSTRAINT configuration_parameter_varchar_fk FOREIGN KEY (configuration_parameter_id) 
     REFERENCES public.configuration_parameter (id) MATCH SIMPLE 
     ON UPDATE RESTRICT ON DELETE RESTRICT 
) 
INHERITS (public.configuration_parameter); 

Как вы можете видеть, parameter_varchar наследуемые от configuration_parameter. Идентификатор всех параметров хранится в параметре configuration_parameter, чтобы избежать двойных идентификаторов параметров. Я хочу иметь список параметров (те, что указаны в родительском, configuration_parameter), которые далее указаны в одном из таких дочерних элементов, как parameter_varchar (или другие параметры children_integer и некоторые другие).

Теперь я хочу добавить параметр. Моя мысль заключалась в том, чтобы сначала добавить строку в родительскую таблицу (configuration_parameter), а затем строку в дочерний элемент (parameter_varchar), чтобы дополнительно указать параметр. Конфигурационный_параметр_ID должен быть таким же, как и номер строки, добавленной в конфигурационный_параметр.

Это заявление я использую:

with inserted as (
INSERT INTO configuration_parameter(type) 
VALUES ('varchar') RETURNING id 
) 
INSERT INTO parameter_varchar(type, configuration_parameter_id, name, is_required, max_length) 
select 'varchar', inserted.id, 'APN Name', 'false', 32 from inserted; 

Что происходит сейчас, есть одна строка в parameter_varchar со всеми вещами, я указал, с ID = 12 и configuration_parameter_id = 11. Но в config_parameter есть 2 строки с id = 11 и id = 12. config_parameter с id = 12 не должно быть.

Либо мое утверждение неверно, либо я неправильно понял какой-то принцип наследования и допустил ошибку в самой БД. Может кто-нибудь объяснить, что я сделал неправильно и почему это пошло не так?

ответ

1

Ваше утверждение неверно, если вы хотите вставить только одну строку.

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

INSERT INTO parameter_varchar(type, name, is_required, max_length) 
    SELECT 'varchar', 'APN Name', 'false', 32 ; 

id колонна наследуется, так parameter_varchar «знает», что это серийный столбец.

+0

Это вызывает ошибку: ОШИБКА: значение null в столбце «configuration_parameter_id» нарушает не-нулевое ограничение – Kailayla

+2

@ Kailayla, этот ответ немного короток. ваш ddl ошибочен. вы либо наследуете, либо относитесь (внешний ключ). вы не можете обойти оба. Я предлагаю вам отказаться от наследства. прочитайте futher [docs] (https://www.postgresql.org/docs/current/static/ddl-inherit.html) –

+0

@A ツ Он может сделать то и другое. Дело не в том, что это неправильно, но в его случае это бессмысленно. –

0

From the manual:

Use of INHERITS creates a persistent relationship between the new child table and its parent table(s). Schema modifications to the parent(s) normally propagate to children as well, and by default the data of the child table is included in scans of the parent(s)

выделено мной. Если вы не хотите этого поведения используйте like в вместо inherits или использовать only в выберите команду:

select * 
from only configuration_parameter 

Но если есть внешний ключ к родителю, то вам не нужно наследование.

Смежные вопросы