Salesforce
Salesforce Object Query Language(SOQL)
サーチ…
構文
- アカウントからのSELECT ID
- SELECT ID、FROMアカウントからの名前
- アカウントからのSELECT Id WHERE Name = 'SomeAccountName'
- SELECT ID、名前、(SELECT ID、FROM連絡先の名前)FROMアカウント
- SELECT ID、FROMアカウントからのID WHERE Id =:apexVariableName
基本的なSOQLクエリ
SELECT Id, Name FROM Account
これにより、AccountテーブルのIdフィールドとNameフィールドが返されます。フィルタリングや並べ替えは適用されません。
フィルタリングによるSOQLクエリ
SELECT Name FROM User WHERE IsActive = true
これにより、アクティブなすべてのユーザーの名前が返されます。
SELECT Name, Phone FROM Contact WHERE CreatedDate >= 2016-01-01T00:00:00.000Z
これにより、2016年1月1日以降に作成された連絡先が返されます。
SELECT Id, Name FROM Account LIMIT 100
これにより、順序付けられていないリストから最初の100個のアカウントが返されます。
SELECT Id, Name, Phone FROM Lead WHERE Phone LIKE '(%) %-%'
これにより、指定された形式に一致する電話番号のリードが返されます。 "%"はワイルドカード文字として機能します。
LIKE '% %'
を使用すると、開発者はCONTAINS( )
式をレプリケートできます。
SELECT Email FROM Lead WHERE LeadSource LIKE '%Google%'
リードソースにはGoogleを含むリードソース、つまり「Google AdWords」と「Google Natural Search」が返されます。
オーダーによるSOQLクエリ
SELECT Id, Name FROM User ORDER BY LastName
SELECT Id, Name FROM Contact ORDER BY LastModifiedDate DESC
SELECT Name, Title FROM User ORDER BY Title ASC NULLS FIRST
SELECT Id FROM Contact ORDER BY LastName ASC NULLS LAST, FirstName ASC NULLS FIRST
SOQLを使用したマップの作成
多くの人が見落とす非常に便利な機能は、SOQLクエリを使用してMapを構築する機能です。
Map<Id, Account> accounts = new Map<Id, Account>([SELECT Id, Name FROM Account]);
System.debug(accounts);
このコードを実行すると、 accounts
には、IDをキーとするアカウントオブジェクトのマップが含まれます。デバッグログへの出力は次のようになります。
11:15:10:025 USER_DEBUG [13]|DEBUG|{
XXXXXXXXXXXXXXXXXX=Account:{Id=XXXXXXXXXXXXXXXXXX, Name=Account 1},
YYYYYYYYYYYYYYYYYY=Account:{Id=YYYYYYYYYYYYYYYYYY, Name=Account 2},
ZZZZZZZZZZZZZZZZZZ=Account:{Id=ZZZZZZZZZZZZZZZZZZ, Name=Account 3},
...
}
これで、自分のIDを使ってAccountオブジェクトを検索できます。さらに、一意のIDのコレクションが必要な場合は、次のようにMapクラスのkeySet()
関数を呼び出すことができます。
System.debug(accounts.keySet());
これはデバッグログで次のようになります。
11:23:21:010 USER_DEBUG [15]|DEBUG|{XXXXXXXXXXXXXXXXXX, YYYYYYYYYYYYYYYYYY, ZZZZZZZZZZZZZZZZZZ, ...}
これは、レコードを取得してコード内で繰り返しアクセスするためにクエリする必要がある場合に非常に便利です。
親オブジェクトのフィールドを参照するためのSOQLクエリ
オブジェクトがルックアップまたはマスター/ディテール関係でリンクされている場合、親レコードフィールドは、子レコードまたはクエリの「ベースオブジェクト」から参照できます。これは上向きのトラバーサルとも呼ばれます。
SELECT FirstName, Account.Name, Account.Category__c FROM Contact
5つのレコードを上にトラバースすることは可能です。
SELECT Account.Owner.Profile.CreatedBy.Name FROM Contact
ベースオブジェクトがカスタムルックアップフィールドの場合、たとえば、フィールド名のPrimary_Influencer__cの__cが__rに変更されます。
SELECT Primary_Influencer__r.Nickname__c FROM Contact
子レコードを取得するためのSOQLクエリ
SELECT Id, Name, (SELECT Id, FirstName, LastName FROM Contacts) FROM Account
ApexでのSOQLクエリ
Apexでクエリを実行するには、クエリを角かっこで囲みます。結果をリストまたは単一のオブジェクトに割り当てることができます。
List<Account> allAccounts = [SELECT Id, Name FROM Account];
Account oldestAccount = [SELECT Id, Name FROM Account ORDER BY CreatedDate LIMIT 1];
ApexのSOQLクエリの変数参照
クエリ内の変数を参照するには、変数名の前にコロン(:)を追加します。
Datetime targetDate = Datetime.now().addDays(-7);
List<Lead> recentLeads = [SELECT Id FROM Lead WHERE CreatedDate > :targetDate];
string targetName = 'Unknown';
List<Contact> incompleteContacts = [SELECT Id FROM Contact WHERE FirstName = :targetName];
ApexのSOQLクエリの潜在的な例外
単一のオブジェクトに代入する場合、単一の行以外のものを返すクエリは、 QueryException
をスローします。
try {
Account a = [SELECT Id FROM Account WHERE Name = 'Non-existent Account'];
} catch (QueryException e) {
// List has no rows for assignment to SObject
}
try {
Account a = [SELECT Id FROM Account];
} catch (QueryException e) {
// List has more than 1 row for assignment to SObject
}
クエリに含まれていないフィールドを使用しようとすると、 SObjectException
がスローされます
Account a = [SELECT Id FROM Account LIMIT 1];
try {
System.debug( a.Name );
} catch (SObjectException e) {
// SObject row was retrieved via SOQL without querying the requested field: Name
}
半結合を使用する
その下に機会レコードが開いているすべてのアカウントを選択する
SELECT Id, Name FROM Account WHERE AccountId IN
(SELECT Id FROM Opportunity WHERE IsClosed = false)
動的SOQL
通常のSOQL式ではなく、Stringからデータベースクエリを実行できます。
String tableName = 'Account';
String queryString = 'SELECT Id FROM ' + tableName + ' WHERE CreatedDate >= YESTERDAY';
List<SObject> objects = Database.query(queryString);
動的SOQLクエリはコンパイルされないので、そのスキーマ参照は検証されないため、可能であれば:variable
構文を使用してApex変数補間を使用することをお勧めします。