Вставка ссылок на себя в Postgresql - PullRequest
9 голосов
/ 24 января 2010

Учитывая следующую таблицу в PostgreSQL, как мне вставить запись, которая ссылается на себя?

CREATE TABLE refers (
    id        SERIAL  PRIMARY KEY,
    name      VARCHAR(255) NOT NULL,
    parent_id INTEGER      NOT NULL,
    FOREIGN KEY (parent_id) REFERENCES refers(id)
);

Примеры, которые я нахожу в Интернете, позволили parent_id быть NULL и затем использовать триггер для его обновления Я бы предпочел обновить за один раз, если это возможно.

Ответы [ 2 ]

11 голосов
/ 24 января 2010

Вы можете выбрать last_value из последовательности, которая создается автоматически при использовании типа serial:

create table test (
  id serial primary key,
  parent integer not null,
  foreign key (parent) references test(id)
);

insert into test values(default, (select last_value from test_id_seq));
insert into test values(default, (select last_value from test_id_seq));
insert into test values(default, (select last_value from test_id_seq));

select * from test;
 id | parent
----+--------
  1 |      1
  2 |      2
  3 |      3
(3 rows)

И, кажется, работает еще проще:

insert into test values(default, lastval());

Хотя я не знаю, как это будет работать при использовании нескольких последовательностей ... Я посмотрел на это; lastval () возвращает последнее значение, возвращенное или установленное с последним вызовом nextval или setval для любой последовательности, поэтому следующее может привести к неприятностям:

create table test (
  id serial primary key,
  foo serial not null,
  parent integer not null,
  foreign key (parent) references test(id)
);

select setval('test_foo_seq', 100);

insert into test values(default, default, lastval());
ERROR:  insert or update on table "test" violates foreign key constraint "test_parent_fkey"
DETAIL:  Key (parent)=(101) is not present in table "test".

Однако, все будет в порядке:

insert into test values(default, default, currval('test_id_seq'));

select * from test;
 id | foo | parent
----+-----+--------
  2 | 102 |      2
(1 row)
2 голосов
/ 24 января 2010

Главный вопрос - зачем вам вставлять запись, которая относится к самой себе?

Схема выглядит как стандартный список смежности - один из способов реализации деревьев в реляционной базе данных.

Дело в том, что в большинстве случаев у вас просто есть parent_id NULL для элемента верхнего уровня. На самом деле это гораздо проще.

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