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

動的 DML

Describe Information を照会し、実行時に SOQL クエリの構築を行うことができます。さらに sObject を動的に作成し、DML を使用してそれらをデータベースに挿入することもできます。

指定されたデータ型の新規 sObject を作成するには、sObject トークンで newSObject メソッドを使用します。トークンは、具体的な sObject のデータ型 (Account など) にキャストする必要があります。次に例を示します。

1// Get a new account
2Account a = new Account();
3// Get the token for the account
4Schema.sObjectType tokenA = a.getSObjectType();
5// The following produces an error because the token is a generic sObject, not an Account
6// Account b = tokenA.newSObject();
7// The following works because the token is cast back into an Account
8Account b = (Account)tokenA.newSObject();

sObject トークン tokenA は Account のトークンですが、別々にアクセスされるため sObject とみなされます。newSObject メソッドを使用するには、具体的な sObject のデータ型 Account にこのトークンを再度キャストする必要があります。割り当てについての詳細は、「クラスとキャスト」を参照してください。

newSObject で ID を指定して、既存のレコードを参照する sObject を作成し、後でそのレコードを更新することもできます。次に例を示します。

1SObject s = Database.query('SELECT Id FROM account LIMIT 1')[0].getSObjectType().
2                                       newSObject([SELECT Id FROM Account LIMIT 1][0].Id);

「SObjectType クラス」を参照してください。

動的 sObject の作成例

この例では、Schema.getGlobalDescribe メソッドを介して sObject トークンを取得し、その後、トークンに対して newSObject メソッドを使用して新しい sObject を作成する方法を示します。 この例にも、取引先の動的作成を検証するテストメソッドが含まれます。

1public class DynamicSObjectCreation {
2    public static sObject createObject(String typeName) {
3        Schema.SObjectType targetType = Schema.getGlobalDescribe().get(typeName);
4        if (targetType == null) {
5            // throw an exception
6        }
7        
8        // Instantiate an sObject with the type passed in as an argument
9        //  at run time.
10        return targetType.newSObject(); 
11    }
12}
1@isTest
2private class DynamicSObjectCreationTest {
3    static testmethod void testObjectCreation() {
4        String typeName = 'Account';
5        String acctName = 'Acme';
6        
7        // Create a new sObject by passing the sObject type as an argument.
8        Account a = (Account)DynamicSObjectCreation.createObject(typeName);        
9        System.assertEquals(typeName, String.valueOf(a.getSobjectType()));
10        // Set the account name and insert the account.
11        a.Name = acctName;
12        insert a;
13
14        // Verify the new sObject got inserted.
15        Account[] b = [SELECT Name from Account WHERE Name = :acctName];
16        system.assert(b.size() > 0);
17    }
18}

項目値の設定と取得

String として表される API 参照名、または項目トークンのいずれかを使用している項目値を設定または取得するには、オブジェクトの get メソッドおよび put メソッドを使用します。次の例では、項目 AccountNumber の API 参照名が使用されます。

1SObject s = [SELECT AccountNumber FROM Account LIMIT 1];
2Object o = s.get('AccountNumber');
3s.put('AccountNumber', 'abc');

次の例では、代わりに AccountNumber 項目のトークンを使用します。

1Schema.DescribeFieldResult dfr = Schema.sObjectType.Account.fields.AccountNumber;
2Sobject s = Database.query('SELECT AccountNumber FROM Account LIMIT 1');
3s.put(dfr.getsObjectField(), '12345');

Object スカラーデータ型は、sObject の項目値を設定または取得するために、汎用データ型として使用できます。これは、anyType 項目のデータ型と同等です。Object データ型は、sObject の汎用型として使用可能な sObject データ型とは異なります。

項目に割り当てた文字列値が長すぎる場合、API バージョン 15.0 以降を使用して保存 (コンパイル) した Apex クラスとトリガにはランタイムエラーが発生します。

メモ

外部キーの設定と取得

Apex は、API と同じ方法で、名前 (または外部 ID) による外部キーの入力をサポートします。外部キーのスカラー ID 値を設定または取得するには、get メソッドまたは put メソッドを使用します。

外部キーに関連付けられたレコードを設定または取得するには、getSObject メソッドと putSObject メソッドを使用します。これらのメソッドは、Object データ型ではなく sObject データ型で使用される必要があります。次に例を示します。

1SObject c = 
2   Database.query('SELECT Id, FirstName, AccountId, Account.Name FROM Contact LIMIT 1');
3SObject a = c.getSObject('Account');

子 sObject を使用しているときに親 sObject 値の外部 ID を指定する必要はありません。親 sObject に ID を提供した場合、DML 操作によって無視されます。Apex は、常に入力した ID で親オブジェクトを返すリレーション SOQL クエリを介して、外部キーが入力されることを前提としています。ID がない場合、子オブジェクトに使用します。

たとえば、カスタムオブジェクト C1 に、親カスタムオブジェクト C2 にリンクする外部キー C2__c があるとします。C1 オブジェクトを作成し、値 C2__r が割り当てられた「AW Computing」という名前の C2 レコードに関連付けるとします。親から子へのリレーションを介して入力されるため、「AW Computing」レコードの ID は不要です。次に例を示します。

1insert new C1__c(Name = 'x', C2__r = new C2__c(Name = 'AW Computing'));

C2__r の ID に値を割り当てている場合、その値は無視されます。ID がない場合、レコードではなくオブジェクト (C2__c) に割り当てます。

動的 Apex を使用して外部キーにアクセスすることもできます。次の例は、動的 Apex を使用して、親-子リレーションのサブクエリから値を取得する方法を示しています。
1String queryString = 'SELECT Id, Name, ' + 
2           '(SELECT FirstName, LastName FROM Contacts LIMIT 1) FROM Account';
3SObject[] queryParentObject = Database.query(queryString);
4         
5for (SObject parentRecord : queryParentObject){ 
6    Object ParentFieldValue = parentRecord.get('Name'); 
7    // Prevent a null relationship from being accessed
8    SObject[] childRecordsFromParent = parentRecord.getSObjects('Contacts');
9    if (childRecordsFromParent != null) {
10        for (SObject childRecord : childRecordsFromParent){ 
11            Object ChildFieldValue1 = childRecord.get('FirstName'); 
12            Object ChildFieldValue2 = childRecord.get('LastName'); 
13            System.debug('Account Name: ' + ParentFieldValue + 
14            '. Contact Name: '+ ChildFieldValue1 + ' ' + ChildFieldValue2);
15        }
16    }              
17}