複数条件での検索 (動的SOQL)
複数の入力フォームに値を入力し、その値を検索条件として値を取得するコードのサンプルです。 例えば下記の様なフォームがあるとします。
このフォームの場合、レコードの検索条件としては下記の4パターンが考えられます。
・名前も年齢も入力されていない →全てのレコードを取得 ・名前のみ入力されている →名前の前方・後方一致で当てはまるレコードを取得 ・年齢のみ入力されている →年齢が一致するレコードを取得 ・名前も年齢も入力されている →名前が前方・後方一致かつ、年齢が一致するレコードを取得
つまりユーザの操作によって4パターンのSOQLが発行されることになります。
if(String.isBlank(inputName) && String.isBlank(inputAge)){ // 名前も年齢も入力されていない Hoge__c[] hogeList = [SELECT Name, Age__c FROM Hoge__c]; }else if(!String.isBlank(inputName) && String.isBlank(inputAge)){ // 名前のみ入力されている Hoge__c[] hogeList = [SELECT Name, Age__c FROM Hoge__c WHERE Name LIKE :name] }else if(String.isBlank(inputName) && !String.isBlank(inputAge)){ // 年齢のみ入力されている Hoge__c[] hogeList = [SELECT Name, Age__c FROM Hoge__c WHERE Age__c = :age] }else{ //名前も年齢も入力されている Hoge__c[] hogeList = [SELECT Name, Age__c FROM Hoge__c WHERE Name LIKE :name AND Age__c = :age] }
この方法では、WHERE句のみが違う同じようなコードを何回も書かないといけません。 今回は入力フォームが二つなので4パターンで済みますが、これがもっとたくさんある場合はその都度同じようなSOQLの文を書かないといけないので面倒です。
おまけに名前の検索時は%田中%
みたいに自分でワイルドカード(%)を付けてやらないと前方・後方一致検索できません。
これを解決するのが動的SOQLと呼ばれるものです。 先ほどのコードに書いてあるSOQLは静的SOQLと呼ばれます。
動的SOQLはDatabase.query(String)
メソッドを使用して、引数に文字列でSOQL文を渡してやることでレコードを取得します。
// 静的SOQL Hoge__c[] hogeList = [SELECT Name, Age__c FROM Hoge__c]; // 動的SOQL Hoge__c[] hogeList = Database.query('SELECT Name, Age__c FROM Hoge__c');
動的SOQLはSOQL文が文字列なので、Database.query(String)
メソッドを呼び出す前に、条件分岐でsoql文を作り変えてやれば画面の入力値に応じて発行されるsoql文が変化します。
先ほどの静的SOQLで書いたコードを動的SOQLで書き直したコントローラのサンプルコードを記載します。
public class SampleSearchController { // フォーム入力用変数 public String inputName {get;set;} public String inputAge {get;set;} // 検索するオブジェクト public Hoge__c[] hogeList{get;set} // コンストラクタ public SampleSearchController(){ hogeList = new List<Hoge__c>(); } // 検索メソッド public void search(){ String soql = 'SELECT Id, Name, Age__c FROM Hoge__c'; String where = ' WHERE ' String soqlName = 'Name LIKE \'%' + String.escapeSingleQuotes(inputName) + '%\''; String soqlAge = 'Age__c = ' + String.escapeSingleQuotes(inputAge); if(!String.isBlank(inputName) && !String.isBlank(inputAge)){ // 名前も年齢も入力されている soql += where + soqlName + ' AND ' + soqlAge; }else if(!String.isBlank(inputName) && String.isBlank(inputAge)){ // 名前のみ入力されている soql += where + soqlName; }else if(String.isBlank(inputName) && !String.isBlank(inputAge)){ // 年齢のみ入力されている soql += where + soqlAge; } System.debug(soql); hogeList = Database.query(soql); } }
このようにSOQL文を文字列で扱うことで、入力された値によって動的にSOQL文を変化させることが出来ます。 ついでにワイルドカード(%)も変数の中に埋め込んでいるので、入力フォームにワイルドカード(%)を入れなくても前方・後方一致検索ができます。