2012-02-17 21 views
11

Oracleに正確に存在しないIngresの "tbl1からtbl1を更新する"コマンドを複製しようとしています。Oracle - 更新結合 - 非キー保存テーブル

私は "update(select 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は、私が何の一意性違反がないことを満足するだろうというのが私の選択などを定義することができますか?

答えて

18

あなたが書いたUPDATEでの問題は、Oracleが単一tbl1.bに対応し、正確に1 tbl2.c値があることを保証できないということである相関サブクエリ

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') 

でこれを行うことができるはず値。 tbl1の特定の行についてtbl2に複数の行がある場合、相関更新は、単一行の副問合せが複数の行を戻したことを示すエラーをスローします。その場合、副問合せにいくつかのロジックを追加して、その場合に使用する行をtbl2から指定する必要があります。

+0

これは問題を解決するように見えます。それは理にかなっている。 –

1

この文は失敗します(ORA-01779は非キー保存表にマップする列を変更できません)。これはベースtbl1tableを変更しようとし、tbl1表はビューでキー保存されないためです。 (ID、A)はdeptテーブルのキーですが、これは結合のキーではありません。

+0

リンクはもう存在しません。正しいページの情報を更新または要約できますか? – Kosi2801

+0

まだ存在しますが、現在はhttp://docs.oracle.com/cd/E11882_01/server.112/e25494/views.htm#ADMIN11783です。 Oracle 11.2 Database管理者ガイド - >§24ビュー、シーケンス、およびシノニムの管理 - >§キー・プリファード・テーブル – user1136452

関連する問題