【Salesforce】Upsertのキー項目を変更する
ApexでUpsertを使用してレコードを保存した際に、エラーが発生しました。
System.DmlException: Upsert failed. First exception on row 0; first error: DUPLICATE_VALUE, duplicate value found: {!FieldName}の値が重複しているレコードの ID: {!RecordId}: []
重複しているキーがありますよってエラーですね。
よく見るやつです。
{!FieldName}の部分は一意の項目となっています。
Upsertというのは説明するまでもなく、新規のレコードであればInsert、既存のレコードであればUpdateするという処理ですね。
https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/langCon_apex_dml_examples_upsert.htm
通常、既存のレコードかどうかの判断はID項目によって行われるのですが、そのキーとなる項目を変更することが出来るようです。
まず、普通にUpsertする方法です。
Account acc; Account copyAcc; // 取引先を取得する acc = [select Id, Name, CompanyCode__c from Account where Id = 'レコードId' limit 1]; // 取引先をコピーする // CompanyCode__cは外部キー項目 copyAcc = acc.clone(false, true); upsert copyAcc;
この場合、CompanyCode__cが重複して上のようなエラーが発生します。
こちらがキーを指定する方法です。
Account acc; Account copyAcc; // 取引先を取得する acc = [select Id, Name, CompanyCode__c from Account where Id = 'レコードId' limit 1]; // 取引先をコピーする // CompanyCode__cは外部キー項目 copyAcc = acc.clone(false, true); upsert copyAcc CompanyCode__c; // キーを指定する
Upsertの際にキー項目を指定することにより、InsertでなくUpdateが行われ、エラーとなりません。
https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_dml_section.htm
指定できるのは外部キーとされている項目だけなので使うことが出来る場面は限られるかもしれません。
しかし、一意の値とするために外部キーが設定されているのであれば、便利ですね。
ちなみに、キー項目を変更してUpsertする場合、リスト内に同じキーが存在するとエラーとなります。
例えば、こんな感じです。
Account acc; List<Account> copyList; // 取引先を取得する acc = [select Id, Name, CompanyCode__c from Account where Id = '0010V00002L9fmQ' limit 1]; // 取引先をコピーする copyList = new List<Account>(); copyList.add( acc.clone(false, true) ); copyList.add( acc.clone(false, true) ); upsert copyList CompanyCode__c;
エラーメッセージです。
System.DmlException: Upsert failed. First exception on row 0; first error: DUPLICATE_VALUE, Duplicate external id specified: 12345: [CompanyCode__c]
気を付けます。
No comments.