ORA-01779 BYPASS_UJVC

結合ビュー(Join View)に対してUPDATEを実施すると、2つの表の主キーが一致しておらず内容的にも重複がある可能性がある(対象表の同一行を複数回更新する)場合に発生する。

ORA-01779:
 複数表にマップする列を変更できません。(Oracle8iの場合)
 キー保存されていない表にマップする列は変更できません(Oracle9iの場合)

原因:
 キー保存されていない表にマップする結合ビューの列を挿入または更新しようとしました。
処置:
 基礎となる実表を直接変更してください。


結合キーが一意でない結合ビュー(Join View)に対して UPDATEを実施したい場合、Oracle8i以降の環境では BYPASS_UJVCというヒントを付けて実行するとORA-1779エラーがしない。
実際にデータ上重複することなくても、オラクルがそのように判断する事があるので、これを回避するためのもである。

ただし、BYPASS_UJVCは、11gから使用できないので注意

BYPASS_UJVC の意味は Updatable Join View Check らしい



わかりやすくいうと、1:nの関係にあるテーブルどうして、更新をかけたときに、どうなるかということである。
更新先1行 ←更新元N行 の関係が問題となる。
(更新先N行←更新元1行 は全く問題ない)
結果はどうなるのか?
実験したところ、N回更新されて、最後の行だけが有効になっているようである。



SELECT /*+ BYPASS_UJVC*/
	 AAA.KEY1
	,AAA.DATA1 AAA_DATA1
	,BBB.DATA1 BBB_DATA1
FROM AAA
INNER JOIN BBB
ON BBB.KEY1 = AAA.KEY1
ORDER BY BBB.DATA1

f:id:nabe_shodai:20141115125035p:plain

--Oracle11g

UPDATE
(
	SELECT /*+ BYPASS_UJVC*/
		 AAA.KEY1
		,AAA.DATA1 AAA_DATA1
		,BBB.DATA1 BBB_DATA1
	FROM AAA
	INNER JOIN BBB
	ON BBB.KEY1 = AAA.KEY1
	ORDER BY BBB.DATA1
) UPD
SET
	AAA_DATA1 = AAA_DATA1 || '-' || BBB_DATA1

Error
[row:13,col:2] ORA-01779: キー保存されていない表にマップする列は変更できません

MERGE文に書き換えても、1:Nの関係は変わらず、違うエラーとして発生する

--Oracle11g
MERGE INTO AAA

USING BBB
ON (BBB.KEY1 = AAA.KEY1)

WHEN MATCHED THEN
	UPDATE
	SET
		AAA.DATA1 = AAA.DATA1 || '-' || BBB.DATA1
Error
[row:3,col:7] ORA-30926: ソース表の安定したセット行を取得できません

なので、更新元の行が1行になるように、データを加工する必要がある。
この例では、KEY1のMAX値をとるようにしてみた。

UPDATE方式だとエラーになるが、
MERRGE方式だとエラーにならない。

--Oracle11g
UPDATE
(
	SELECT /*+ BYPASS_UJVC*/
		 AAA.KEY1
		,AAA.DATA1 AAA_DATA1
		,BBB.DATA1 BBB_DATA1
	FROM AAA
	INNER JOIN (
		SELECT KEY1,MAX(DATA1) DATA1 FROM BBB GROUP BY KEY1
	)BBB
	ON BBB.KEY1 = AAA.KEY1
	ORDER BY BBB.DATA1
) UPD
SET
	AAA_DATA1 = AAA_DATA1 || '-' || BBB_DATA1

Error
[row:16,col:2] ORA-01779: キー保存されていない表にマップする列は変更できません
--Oracle11g

MERGE INTO AAA

USING(SELECT KEY1,MAX(DATA1) DATA1 FROM BBB GROUP BY KEY1)BBB
ON (BBB.KEY1 = AAA.KEY1)

WHEN MATCHED THEN
	UPDATE
	SET
		AAA.DATA1 = AAA.DATA1 || '-' || BBB.DATA1

f:id:nabe_shodai:20141115142703p:plain