この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

Apex データ操作言語

このチュートリアルのこれまでのレッスンでは、sObject の概要、sObject のクエリ方法、および sObject 間のリレーションをトラバースする方法を見てきました。ここでは、Apex データ操作言語 (DML) を使用してデータベースのレコードを操作する方法を学習します。DML を使用すると、データベース内のデータを挿入、更新、削除、または復元できます。

次の例では、insert をコールして新しい請求書明細を挿入します。実際に試してみましょう。
1Invoice_Statement__c inv = new Invoice_Statement__c(Description__c='My new invoice');
2// Insert the invoice using DML.
3insert inv;

請求書明細を挿入すると、sObject 変数 inv には新しい請求書明細の ID が入ります。

今度は、請求書明細の状況を変更して更新しましょう。次のコードを実行して、挿入した請求書明細の状況を変更し、データベースのレコードを更新します。
1// First get the new invoice statement
2Invoice_Statement__c inv = [SELECT Status__c 
3                            FROM Invoice_Statement__c 
4                            WHERE Description__c='My new invoice'];
5// Update the status field
6inv.Status__c = 'Negotiating';
7update inv;
この請求書明細は完了したので、delete ステートメントを使用して削除しましょう。次のサンプルを実行します。
1// First get the new invoice statement
2Invoice_Statement__c inv = [SELECT Status__c 
3                            FROM Invoice_Statement__c 
4                            WHERE Description__c='My new invoice'];
5delete inv;
レコードを削除すると、そのレコードはごみ箱に入り、そこから復元できます。ごみ箱のレコードは一時的に 15 日間保存された後、完全に削除されます。レコードを復元するには、undelete DML ステートメントを使用するだけです。削除したレコードを取得できるように SOQL クエリでは ALL ROWS キーワードを使用しています。
1Invoice_Statement__c inv = [SELECT Status__c 
2                            FROM Invoice_Statement__c 
3                            WHERE Description__c='My new invoice'
4                            ALL ROWS];
5undelete inv;

Apex は、mergeupsert などその他の DML 操作もサポートします。詳細は、Force.com Apex コード開発者ガイド』を参照してください。

メモ

Database DML メソッド

別の方法として、Database クラスで提供されるメソッドをコールして DML 操作を実行できます。学習した DML ステートメントには対応する Database メソッドもあり、Database クラス Database.DMLOperation でコールできます。Database DML メソッドは、1 つの sObject または sObject のリストを第 1 引数として取ります。また、省略可能な Boolean 型の第 2 引数 opt_allOrNone も取ります。この引数では、操作の部分的な完了を許可するかどうかを指定します。この引数を false に設定した場合、あるレコードが失敗しても、残りの DML 操作を続行して完了することができます。Database DML メソッドは、実行した DML 操作の結果を返します。

次の例では、2 つの請求書明細を挿入し、部分的な完了を許可します。続いて、DML の結果を反復処理し、失敗したレコードの最初のエラーを取得します。実際に試してみましょう。
1Invoice_Statement__c inv1 = new Invoice_Statement__c(Description__c='My new invoice');
2Invoice_Statement__c inv2 = new Invoice_Statement__c(Description__c='Another invoice');
3// Insert the invoice using DML.
4Database.SaveResult[] lsr = Database.insert(
5                            new Invoice_Statement__c[]{inv1, inv2}, false);
6
7// Iterate through the results and 
8//   get the first error for each failed record.
9for (Database.SaveResult sr:lsr){
10    if(!sr.isSuccess())
11        Database.Error err = sr.getErrors()[0];
12}

opt_allOrNone 引数を false に設定すると、DML 操作が失敗したときに例外の発生を避けることができます。例外についての詳細は、例外処理で学習します。

メモ

請求書明細が挿入されたら、削除しましょう。次の例は、最初にクエリを実行して前の例で作成した請求書を取得し、削除します。続いて、delete 操作の結果を反復処理し、失敗したレコードの最初のエラーを取得します。次のコードを実行します。
1Invoice_Statement__c[] invs = [SELECT Id 
2                              FROM Invoice_Statement__c 
3                              WHERE Description__c='My new invoice'
4                              OR Description__c='Another invoice'];
5// Delete the invoices returned by the query.
6Database.DeleteResult[] drl = Database.delete(invs, false);
7
8// Iterate through the results and 
9//   get the first error for each failed record.
10for (Database.DeleteResult dr:drl){
11    if(!dr.isSuccess())
12        Database.Error err = dr.getErrors()[0];
13}
前のセクションで説明したように、削除したレコードは 15 日間ごみ箱に置かれます。次の例では、削除したレコードを Database.undelete をコールして復元します。SOQL クエリでは、削除したレコードを��得できるように、ALL ROWS キーワードを使用しています。
1Invoice_Statement__c[] invs = [SELECT Status__c 
2                            FROM Invoice_Statement__c 
3                            WHERE Description__c='My new invoice'
4                            OR Description__c='Another invoice'
5                            ALL ROWS];
6// Restore the deleted invoices.
7Database.UndeleteResult[] undelRes = Database.undelete(invs, false);
8
9// Iterate through the results and 
10//   get the first error for each failed record.
11for (Database.UndeleteResult dr:undelRes){
12    if (!dr.isSuccess())
13        Database.Error err = dr.getErrors()[0];
14}

DML ステートメントと Database DML ステートメントをいつ使用するか

通常、opt_allOrNone 引数を false に設定して一括 DML 操作の部分的な完了を許可する場合は DML ステートメントではなく Database メソッドを使用します。この方法では、コードで例外が発生するのを回避し、返された結果から拒否されたレコードを調査し、可能ならば操作を再試行できます (例外については次の例外処理で学習します)。opt_allOrNone 引数を false に設定していなければ、Database メソッドは例外もサポートします。

DML 一括処理中のエラーを Apex 例外としてスローし、制御の流れを直ちに中断する場合は DML ステートメントを使用します。これは try/catch ブロックを使用して処理できます。この動作は、ほとんどのデータベース手続き型言語での例外の処理方法に似ています。