Oracle - обновление соединения - таблица без сохранения ключей - PullRequest
12 голосов
/ 18 февраля 2012

Я пытаюсь реплицировать команду Ingres "update tbl1 from tbl2", которой нет в Oracle.

Поэтому я использую команду «update (выберите tbl1 join tbl2 ...)». В обеих таблицах определены первичные ключи, и я подумал , что мое объединение однозначно идентифицировало строки, но я все еще получаю "ORA-01779: невозможно изменить столбец, который сопоставляется с таблицей без сохранения ключей".

Вот подходящие анонимные определения таблиц и обновление, которое я пытаюсь выполнить:

CREATE TABLE tbl1
(
   ID decimal(11) NOT NULL,
   A varchar2(3) NOT NULL,
   B float(7),
   CONSTRAINT tbl1_pk PRIMARY KEY (ID,A)
)
;

CREATE TABLE tbl2
(
   ID decimal(11) NOT NULL,
   A varchar2(3) NOT NULL,
   B float(15),
   C float(15),
   D char(1) NOT NULL,
   CONSTRAINT tbl2_PK PRIMARY KEY (ID,A,D)
)
;

UPDATE 
  (select tbl1.b, tbl2.c 
   from tbl1 inner join tbl2 
   on tbl1.id=tbl2.id 
   and tbl1.a=tbl2.a 
   and tbl1.b=tbl2.b 
   and tbl1.a='foo' 
   and tbl2.D='a') 
set b=c;

Как я могу определить свой выбор так, чтобы Oracle был удовлетворен тем, что у меня нет нарушений уникальности?

Ответы [ 3 ]

23 голосов
/ 18 февраля 2012

Вы должны быть в состоянии сделать это с помощью коррелированного подзапроса

UPDATE tbl1 t1
   SET t1.b = (SELECT c
                 FROM tbl2 t2
                WHERE t1.id = t2.id
                  AND t1.a  = t2.a
                  AND t1.b  = t2.b
                  AND t2.d  = 'a')
 WHERE t1.a = 'foo'
   AND EXISTS( SELECT 1
                 FROM tbl2 t2
                WHERE t1.id = t2.id
                  AND t1.a  = t2.a
                  AND t1.b  = t2.b
                  AND t2.d  = 'a')

Проблема с написанным вами UPDATE состоит в том, что Oracle не может гарантировать, что существует ровно 1 tbl2.c значение, котороесоответствует одному значению tbl1.b.Если в tbl2 имеется несколько строк для какой-либо конкретной строки в tbl1, коррелированное обновление выдаст ошибку, указывающую, что подзапрос из одной строки возвратил несколько строк.В этом случае вам необходимо добавить некоторую логику в подзапрос, чтобы указать, какую строку из tbl2 использовать в этом случае.

1 голос
/ 23 апреля 2013

Этот оператор завершается ошибкой (ORA-01779 не может изменить столбец, который сопоставляется с таблицей без сохранения ключа), поскольку он пытается изменить базовую таблицу tbl1, а таблица tbl1 не сохраняется в представлении ключа в представлении. поскольку (ID, A) является ключом таблицы dept, он не является ключом объединения.

0 голосов
/ 12 августа 2014

Похоже, что ваше представление не является сохраненным ключом представлением согласно (http://www.orafaq.com/tuningguide/updateable%20view.html). Действительно, вы выполняете соединение по не первичному ключу, который, по-видимому, недопустим.

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