この文章は 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}