Я пытался вставить данные в самоссылающуюся таблицу, в то время как данные были получены из других разных таблиц. Эта строка является своего рода корневой записью и должна иметь собственную ссылку в качестве внешнего ключа. Для облегчения понимания приведем здесь таблицу DDL -
CREATE TABLE self_refer (
id SERIAL PRIMARY KEY,
parent_id INTEGER NOT NULL,
FOREIGN KEY (parent_id) REFERENCES self_refer(id)
);
Если мы хотим вставить данные с использованием прямых значений, это обсуждаемая тема здесь , и приведенный ниже оператор работает хорошо.
INSERT INTO self_refer
(parent_id)
VALUES ((SELECT last_value
FROM self_refer_id_seq))
В моем случае мне нужно вставить данные из других таблиц, и, таким образом, оператор будет иметь тип INSERT INTO SELECT
. Ниже приведены мои попытки, и они не работают должным образом.
INSERT INTO self_refer
(parent_id)
SELECT CURRVAL('self_refer_id_seq')
и
INSERT INTO self_refer
(parent_id)
SELECT last_value
FROM self_refer_id_seq
Первый оператор с VALUES
вставляет данные соответствующим образом, но второй и третий вытягиваютпредварительные данные для last_value
или currval
. Первый запрос работает хорошо даже при использовании с функцией currval
.
Ниже приведены результаты, где первые две записи показывают вставку через VALUES
, а следующие две - с операторами INSERT INTO SELECT
.
id|parent_id|
--|---------|
47| 47|
48| 48|
49| 48|
50| 49|
Нужна помощь по достижению результатов, таких как первые две строки, с сохранением операторов SQL, аналогичных вторым двум.
Обновление: Принятый ответ работает, но может и не работатьбыть идеальным решением, прочитайте все комментарии о том, как было получено лучшее решение.
Добавлены приведенные ниже утверждения для более быстрого доступа. Не стесняйтесь проверить db fiddle , если предпочитаете настроить и попробовать другие возможности.
CREATE TABLE self_refer (
id SERIAL PRIMARY KEY,
parent_id INTEGER NOT NULL,
FOREIGN KEY (parent_id) REFERENCES self_refer(id)
);
✓
INSERT INTO self_refer
(parent_id)
VALUES ((SELECT last_value
FROM self_refer_id_seq))
1 rows affected
INSERT INTO self_refer
(parent_id)
SELECT CURRVAL('self_refer_id_seq')+1;
1 rows affected
select * from self_refer;
id | parent_id
-: | --------:
1 | 1
2 | 2
INSERT INTO self_refer
(parent_id)
VALUES ((SELECT last_value
FROM self_refer_id_seq))
1 rows affected
select * from self_refer;
id | parent_id
-: | --------:
1 | 1
2 | 2
3 | 3
INSERT INTO self_refer
(parent_id)
SELECT CURRVAL('self_refer_id_seq')+1;
1 rows affected
select * from self_refer;
id | parent_id
-: | --------:
1 | 1
2 | 2
3 | 3
4 | 4
INSERT INTO self_refer
(parent_id)
SELECT last_value +1
FROM self_refer_id_seq
1 rows affected
select * from self_refer;
id | parent_id
-: | --------:
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
insert into self_refer values(default, (currval('self_refer_id_seq')));
1 rows affected
select * from self_refer;
id | parent_id
-: | --------:
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
CREATE FUNCTION my_trigger_function()
RETURNS trigger AS '
BEGIN
IF NEW.parent_id = -1 THEN
NEW.parent_id := NEW.id;
END IF;
return new;
END ' LANGUAGE 'plpgsql'
✓
create trigger test_t
before insert on self_refer
for each row
EXECUTE PROCEDURE my_trigger_function()
✓
INSERT INTO self_refer
(parent_id)
SELECT -1
1 rows affected
select * from self_refer;
id | parent_id
-: | --------:
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
7 | 7
INSERT INTO self_refer
(parent_id)
SELECT 5
1 rows affected
select * from self_refer;
id | parent_id
-: | --------:
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
7 | 7
8 | 5
дБ <>скрипка здесь