0

マージ コマンドを使用して、存在しないレコードをテーブルに挿入しています。単純な挿入コマンドを使用すると、正常に機能します。マージ システムを使用すると、常に警告 ORA-00904: "T"."GROUP_COMPANY_ID" 無効な識別子が表示されます。ON 条件を (1=1) に変更して強制的に true にすると、マージ コマンドは正常に機能します。

元のマージステートメントが間違っているのは何ですか? 二重引用符で囲まれた名前なしでテーブルが作成されたと確信しているため、ここでは大文字と小文字の問題はありません。

create table test
(
  create_date      DATE not null,
  group_company_id CHAR(16) not null
)

-- This is okay
INSERT INTO test (create_date, group_company_id) VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc');

-- This one will raise ORA-00904 error
MERGE INTO test T
USING (SELECT 'abc' AS group_company_id FROM DUAL) C
   ON (T.group_company_id = C.group_company_id)
-- ON (1 = 1)
WHEN NOT MATCHED THEN
     INSERT (create_date, group_company_id)
     VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc')
WHEN MATCHED THEN
     UPDATE SET group_company_id = 'abc';
4

3 に答える 3

8

参加している列を更新することはできません。

于 2011-11-25T08:49:30.673 に答える
1

あなたのコードはORA-00904を投げません、それは自明のORA-38104を投げます

SQL> MERGE INTO test T
USING (SELECT 'abc' AS group_company_id FROM DUAL) C
   ON (T.group_company_id = C.group_company_id)
-- ON (1 = 1)
WHEN NOT MATCHED THEN
     INSERT (create_date, group_company_id)
     VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc')
WHEN MATCHED THEN
     UPDATE SET group_company_id = 'abc';
  2    3    4    5    6    7    8    9     ON (T.group_company_id = C.group_company_id)
       *
ERROR at line 3:
ORA-38104: Columns referenced in the ON Clause cannot be updated:
"T"."GROUP_COMPANY_ID"


SQL> 

11gR2 を実行しています。おそらく、以前のリリースでは動作が異なります。とにかく、解決策は非常に簡単です: MATCHED ブランチを気にしないでください:

SQL> MERGE INTO test T
USING (SELECT 'abc' AS group_company_id FROM DUAL) C
   ON (T.group_company_id = C.group_company_id)
-- ON (1 = 1)
WHEN NOT MATCHED THEN
     INSERT (create_date, group_company_id)
     VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc')
  2    3    4    5    6    7    8  /

0 rows merged.

SQL> 

9i で MERGE が導入されたとき、この構文は有効ではありませんでした。両方のブランチを含める必要がありました。ただし、10g 以降でサポートされています。

9i を使用していて MATCHED 分岐が必要な場合は、結合句に含まれていない列を更新する必要があります。あなたの例では CREATE_DATE になります。

于 2011-11-25T11:09:56.810 に答える
0

insertandupdate句のテーブル エイリアスを使用して列名を修飾します。

WHEN NOT MATCHED THEN
  INSERT (T.create_date, T.group_company_id)
  VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc')
WHEN MATCHED THEN
  UPDATE SET T.group_company_id = 'abc'; 

編集:

MERGE INTO test  
USING DUAL   
ON (group_company_id = 'abc') 
WHEN NOT MATCHED THEN      
      INSERT VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc');
于 2011-11-25T08:53:41.793 に答える