0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

動的SOQLのバインド変数に関する考慮事項

Posted at

この記事について

Apexの動的SOQLのバインド変数では、通常の静的SOQLのバインド変数と異なる仕様があったため記録する。

オブジェクトのプロパティは使用できない

例えば以下のacc.Idのような、オブジェクトのプロパティを参照するバインド変数だと例外が発生する。
※Apexクラスのインスタンスのプロパティも同様

Account acc = new Account(Name = 'ABC株式会社');
insert acc;

String query = 'SELECT Id FROM Account WHERE Id = :acc.Id'; // "acc.Id"はダメ
List<Account> accounts = Database.query(query); // ここで例外発生:System.QueryException: Variable does not exist: acc.Id

この問題を回避するには、オブジェクトのプロパティを参照しなければよいので、プリミティブ型の変数を作成して使用するとよい。

Account acc = new Account(Name = 'ABC株式会社');
insert acc;

Id accountId = acc.Id; // プリミティブ型の変数を作成し "acc.Id" を代入

String query = 'SELECT Id FROM Account WHERE Id = :accountId'; // オブジェクトのプロパティを参照しないため例外が発生しない
List<Account> accounts = Database.query(query);

Database.queryメソッドの実行時点のスコープ内にある変数名である必要がある。

動的SOQLだとしばしば別のメソッドやQueryBuilderなどのカスタムApexクラスを用いてSOQLを作成することがあるが、バインド変数がDatabase.queryメソッドを実行する際のスコープ内に存在している必要がある。

例えば、以下のような動的SOQLクエリを作成するbuildQueryメソッドがあったとする。

public class SampleQueryBuilder {
    public static String buildQuery(String accountId) {
        return 'SELECT Id FROM Account WHERE Id = :accountId';
    }
}

このメソッドを使用して以下のようなコードを実行した場合、accountIdという変数がDatabase.queryメソッド実行時のスコープ内に存在しないため、例外が発生する。

Account acc = new Account(Name = 'ABC株式会社');
insert acc;

String query = SampleQueryBuilder.buildQuery(acc.Id);

List<Account> accounts = Database.query(query); // ここで例外発生:System.QueryException: Variable does not exist: accountId

この問題を回避するには、バインド変数で使用する変数をDatabase.queryメソッド実行時のスコープ内(Database.queryメソッドを呼び出しているメソッド内)に作成する必要がある。

Account acc = new Account(Name = 'ABC株式会社');
insert acc;

String query = SampleQueryBuilder.buildQuery(acc.Id);

Id accountId = acc.Id; // スコープ内に"accountId"がある状態。クエリの実行時にこの変数が使用される

List<Account> accounts = Database.query(query);
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?