PostgreSQL 11.1
Я давно боролся с этой проблемой. (Я пытался улучшить вопрос раньше).
Проблема: у человека есть два разных имени в таблице tempA. С каждым именем связаны записи в таблице tempB. Как я могу переместить все записи, связанные с одним именем, на другое имя, а затем удалить имя?
Пример: у меня есть два имени - "Том" и "Боб". Я хочу изменить все записи, связанные с «Bob», на «Tom», а затем удалить «Bob» из базы данных.
Как это сделать, сохраняя связанные записи в таблице tempb?
CREATE TABLE tempA
(
id serial PRIMARY KEY,
name text UNIQUE NOT NULL
);
CREATE TABLE tempb
(
id serial PRIMARY KEY,
tempa_id integer NOT NULL,
description text NOT NULL,
CONSTRAINT foo_bar_fk FOREIGN KEY (tempa_id)
REFERENCES tempa (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE NO ACTION
DEFERRABLE INITIALLY DEFERRED
)
INSERT INTO tempA (name) VALUES('tom');
INSERT INTO tempA (name) VALUES('bob');
INSERT INTO tempB (tempA_id, description) SELECT id, 'test1' FROM tempA WHERE tempA.name = 'tom';
INSERT INTO tempB (tempA_id, description) SELECT id, 'test2' FROM tempA WHERE tempA.name = 'tom';
INSERT INTO tempB (tempA_id, description) SELECT id, 'test3' FROM tempA WHERE tempA.name = 'bob';
INSERT INTO tempB (tempA_id, description) SELECT id, 'test4' FROM tempA WHERE tempA.name = 'bob';
Initial set:
-- tempA
id name
1 "tom"
2 "bob"
id tempA_id description
1 1 "test1"
2 1 "test2"
3 2 "test3"
4 2 "test4"
Цель, которую я пытаюсь достичь:
--Desired Results
-- tempA
id name
1 "tom"
-- tempB
id tempA_id description
1 1 "test1"
2 1 "test2"
3 1 "test3"
4 1 "test4"
Это то, что я пытался, но она продолжает терпеть неудачу:
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
-- from 'tom' to 'bob' -- when all is done 'tom' must be the name to keep.
WITH _in (name1, name2) AS(
VALUES('tom','bob')
),
_bob AS( -- DELETING 'bob' record FROM tempA.
DELETE FROM tempA
USING _in
WHERE (tempA.name = _in.name2)
RETURNING tempA.*
)
UPDATE tempA -- REPLACING 'bob' with 'tom'. REPLACING 'bobs' id with 'toms' id.
SET name = _in.name1, id = _tom.id
FROM _in
JOIN _bob ON (_bob.name = _in.name2)
JOIN tempA _tom ON (_tom.name = _in.name1)
WHERE (tempA.id = _bob.id);
COMMIT;
ОШИБКА: обновление или удаление в таблице "tempa" нарушает ограничение внешнего ключа "foo_bar_fk" в таблице "tempb" ПОДРОБНЕЕ: на ключ (id) = (2) все еще ссылаются из таблицы "tempb" .
Кажется Я не могу заставить ОБНОВЛЕНИЕ произойти до принудительного удаления.
Любая помощь наиболее ценится. ТИА