1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Database.query メソッドと動的SOQL

Last updated at Posted at 2025-02-20

Salesforce の Database.query メソッドは、SOQL クエリを動的に組み立てて実行できる便利な方法です。特に、検索条件を動的に変更したい場合や、クエリを組み立てる必要があるケースで使用されます。


基本構文

List<SObject> results = Database.query(String query);
  • query には SOQL 文字列 を指定する。
  • List<SObject> 型で結果を取得するため、型キャストが必要な場合がある。

静的 SOQL と 動的 SOQL の違い

// 静的 SOQL
List<Account> accounts = [SELECT Id, Name FROM Account WHERE Industry = 'Technology'];

// 動的 SOQL
String industryType = 'Technology';
String query = 'SELECT Id, Name FROM Account WHERE Industry = \'' + industryType + '\'';
List<Account> accounts = Database.query(query);

動的 SOQL のメリット:

  • industryType の値を動的に変更できるため、柔軟な検索が可能。
  • WHERE 条件や ORDER BY などを組み合わせた検索を動的に構築できる。

動的 SOQL の具体例

1. ユーザー入力に基づく動的検索

たとえば、IndustryRating を入力してアカウントを検索する場合:

public List<Account> searchAccounts(String industry, String rating) {
    String query = 'SELECT Id, Name, Industry, Rating FROM Account WHERE Industry = \'' + industry + '\'';

    if (rating != null && rating != '') {
        query += ' AND Rating = \'' + rating + '\'';
    }

    return Database.query(query);
}

使用例

List<Account> result = searchAccounts('Technology', 'Hot');

この場合、以下のクエリが実行される:

SELECT Id, Name, Industry, Rating FROM Account WHERE Industry = 'Technology' AND Rating = 'Hot'

動的に AND Rating = 'Hot' の条件が追加される。


2. LIKE を使ったあいまい検索

たとえば、Name に特定のキーワードを含むアカウントを検索する場合:

public List<Account> searchByName(String keyword) {
    String query = 'SELECT Id, Name FROM Account WHERE Name LIKE \'%' + keyword + '%\'';
    return Database.query(query);
}

使用例

List<Account> result = searchByName('Tech');

実行されるクエリ:

SELECT Id, Name FROM Account WHERE Name LIKE '%Tech%'

3. ORDER BY で並び替え

public List<Contact> getSortedContacts(String sortBy) {
    String query = 'SELECT Id, FirstName, LastName FROM Contact ORDER BY ' + sortBy;
    return Database.query(query);
}

使用例

List<Contact> contacts = getSortedContacts('LastName');

実行されるクエリ:

SELECT Id, FirstName, LastName FROM Contact ORDER BY LastName

4. LIMIT と OFFSET を使ったページネーション

public List<Opportunity> getOpportunities(Integer pageNumber, Integer pageSize) {
    Integer offsetValue = (pageNumber - 1) * pageSize;
    String query = 'SELECT Id, Name, Amount FROM Opportunity ORDER BY CloseDate DESC LIMIT ' + pageSize + ' OFFSET ' + offsetValue;
    return Database.query(query);
}

使用例

List<Opportunity> opportunities = getOpportunities(2, 10);

実行されるクエリ(2ページ目、10件表示):

SELECT Id, Name, Amount FROM Opportunity ORDER BY CloseDate DESC LIMIT 10 OFFSET 10

動的 SOQL の注意点

  1. SOQL インジェクション対策

    • 文字列をそのまま連結すると SOQL インジェクション のリスクがある。
    • String.escapeSingleQuotes() を使ってエスケープする。
    String industry = 'Technology\' OR Name != \'\'';
    String query = 'SELECT Id, Name FROM Account WHERE Industry = \'' + String.escapeSingleQuotes(industry) + '\'';
    
  2. ガバナ制限

    • Database.query()SOQL クエリ制限(1トランザクション 100 件)にカウントされる。
    • リスト制限(1クエリの結果 50,000 件)に注意。
  3. 型キャスト

    • Database.query()List<SObject> を返すため、型変換が必要。
    List<Account> accounts = (List<Account>) Database.query(query);
    

まとめ

  • Database.query()SOQL クエリを動的に生成 できる。
  • 検索条件 (WHERE)、ソート (ORDER BY)、ページネーション (LIMIT & OFFSET) を柔軟に変更可能。
  • String.escapeSingleQuotes() を使って SOQL インジェクション対策 をする。
  • ガバナ制限 に注意しながら適切に設計する。

動的 SOQL を活用すれば、ユーザー入力に基づいた 柔軟な検索機能 を実装できます! 🚀

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?