機械翻訳について

問合せヘルパー関数の使用方法

次のセクションでグローバル関数を定義した後、ビジネス・ロジックでは、SQL select文の構造を削除する構文を使用して、問合せタスクを簡単に実行できます。

たとえば、ジョブ・コードが営業担当であるStaffMemberビジネス・オブジェクトの表からEメール、姓および名を問い合せるには、次のようなコードを記述できます:

def salesReps = adf.util.queryMaps(select: 'Email,LastName,FirstName',
                                     from: 'StaffMember',
                                    where: 'JobId = :JobCode',
                                  orderBy: 'LastName,FirstName',
                                    binds: [JobCode: 'SA_REP'])

selectおよびfromの名前付きパラメータのみが必要です。 その他は、使用する必要がある場合にのみ指定します。 queryMaps()関数は、MapオブジェクトのListを返します。各オブジェクトには、selectパラメータで指定したフィールドの値のみが含まれます。

ビジネス・ロジックの一部として更新するために行を取得する必要がある場合は、queryMaps()「代わりに」で、次に示すようにqueryRows()メソッドを使用します。 結果は、更新可能な属性を持つRowオブジェクトのListで、現在のトランザクション内の他の変更済オブジェクトとともに検証および保存されます。 結果はListであるため、forループで直接使用できます。 また、コードがループ内で更新する予定であるselectリストにSalary列が含まれていることにも注意してください。
// Update the salary of sales reps to increase it by 5 percent
for (curRep in adf.util.queryRows(select: 'Salary',
                                    from: 'StaffMember',
                                   where: 'JobId = :JobCode',
                                   binds: [JobCode: 'SA_REP'])) {
  // Round the salary to two digits after increasing by 5%
  curRep.Salary = (curRep.Salary * 1.05 as Double).round(2)
}

where句で単一の行を識別する場合、または結果の最初の行のみを取得する場合は、コンパニオン単一行戻り関数を使用します:

  • Map queryMap(Map options) - 最初の問合せ結果行がMapとして返されるか、行が戻されなかった場合はnullが返されます
  • Object queryRow(Map options) - 最初の問合せ結果行を返すか、行が戻されなかった場合はnullを返します

問合せによって返される行の合計数のみをコンピュートする場合は、queryCount()関数を使用します。 ただし、単一行の存在をテストすることが目的の場合は、queryMap()またはqueryRow()を使用し、戻り値がnullでないかどうかをテストする方が効率的であることに注意してください。

問合せメソッドでサポートされる名前付きパラメータの完全なリストは次のとおりです。 ビジネス・オブジェクト名およびフィールド名を示すすべての場所は、case-sensitiveです。

  • select - ビジネス・オブジェクト・フィールド名のカンマ区切りリスト( String「必要な」)
  • from - ビジネス・オブジェクトの名前( String「必要な」)
  • where - ビュー基準フィルタ述語(オプションでバインド変数を参照するString)
  • orderBy - フィールド名のカンマ区切りリスト(String。オプションで、降順の場合は" desc "のサフィクス)
  • binds - where述語( Map)で参照されるバインド変数名/値のペア
  • ignoreNullBinds - [ Boolean ]がtrueに設定され、nullバインド値を含むwhere述語要素が無視されます

where句では、変数によるユーザー定義に加えて、次の組込みバインド変数名を参照できます:

  • SysUser - 現在ログインしているユーザーの名前、またはそれ以外の場合はanonymous (String)
  • SysToday - 現在の日付( Date)
  • SysNow - 現在の日時( Datetime)

たとえば、現在の日付の為替レートのリストを問合せするには、次のような問合せを作成します。 ユース・ケースでは単一の行を返す必要があり、データの変更を計画していないため、queryMap()を使用して、コードで変換済通貨値のコンピュートに必要な単一のRate_c属性を取得します。

def rate = adf.util.queryMap(
              select: 'Rate_c',
                from: 'ExchangeRate_c',
               where: 'From_c = :Base and To_c = :Other and Date_c = :SysToday',
               binds: [Base: 'GBP', Other: 'EUR'])
def convertedVal = sourceVal * rate.Rate_c
ヘルパー・メソッドqueryRows(), queryMaps(), queryRow(), queryMap()およびqueryCount()は、実装で同じコアquery()ヘルパー関数をコールします。 この機能により、次のことが集中化されます:
  • selectおよびfrom必須オプションが存在することを検証しています
  • fromパラメータで渡されたオブジェクト名を使用したnewView()を使用したビュー・オブジェクトの作成
  • selectリスト・フィールド名をトークン化し、selectAttributesBeforeQuery()に渡す
  • whereおよびbindsパラメータが指定されている場合のユーザー指定のバインド変数の定義
  • whereパラメータが指定されている場合のビュー基準フィルタ式の適用
  • システム変数またはユーザー指定バインド変数(あるいはその両方)の値の設定
  • ビュー・オブジェクトの返却

コードでバインド変数に対して異なる値を使用して同じ問合せを複数回再実行する必要がある場合は、ビュー・オブジェクトを返すコアquery()関数を使用します。 結果を自分で反復し、適切なバインド変数を再割当てして、異なる複数のビュー・オブジェクトを作成せずにビュー・オブジェクトを再度実行できます。 この方法は、単一のトリガーまたはオブジェクト関数でビュー・オブジェクトが多すぎる場合の実行時例外を回避するために重要です。

たとえば、不明な数の未清算トランザクション・レコードを反復処理し、各レコードについて為替レートをターゲット通貨に問い合せる次のコードを考えてみます。 ループ内でqueryMap()関数を使用します。 このアプローチでは、ループの反復ごとに新しいビュー・オブジェクトが1つ作成されます。 反復される行数が予測できないほど大きい場合、この方法では、単一のトリガーまたは関数で作成できるビュー・オブジェクト数の上限に達したときに、ランタイム・リソース例外を生成できます。
// Will be updating the queried rows, so use queryRows()
for (txn in adf.util.queryRows(select:'Id,Cleared_c,Currency_c,Amount_c,Date_c', 
                                 from: 'Transaction_c',
                                where: "Cleared_c = 'N'")) {
  def rate = 1
  // If transaction currency is different than GBP, lookup historical
  // exchange rate for the date of the transaction to convert the 
  // transaction currency into GBP
  if (txn.Currency_c != 'GBP') {
    // NOT BEST PRACTICE: Using a query inside a loop!
    rate = adf.util.queryMap(
              select: 'Rate_c',
                from: 'ExchangeRate_c',
               where: "From_c = :Base and To_c = 'GBP' and Date_c = :ForDate",
               binds: [Base: txn.Currency_c, ForDate: txn.Date_c ])?.Rate_c
  }
  if (rate) {
    txn.Cleared_c = 'Y'
    // Multiply original txn amount by rate and round to 2 decimal places 
    txn.AmountInGBP_c = (txn.Amount_c * rate as Double).round(2)   
  }
}
ループの本文内で問合せ関数を使用するのではなく、コアquery()ヘルパー関数をコールすることをお薦めします。 ループ内で使用できるビュー・オブジェクトを返します。 ループの反復ごとに、バインド変数を適切な値に設定し、問合せを再実行します。 前述のルーチンのこのベスト・プラクティス・リライトを次に示します。
// BEST PRACTICE: Create a reusable query for looking up the exchange rate using
// ~~~~~~~~~~~~~  bind variable values of the correct datatype. Inside the loop
// set the correct bind var values and execute the same view object over & over
def rateVO = adf.util.query(
                select: 'Rate_c',
                  from: 'ExchangeRate_c',
                 where: "From_c = :Base and To_c = 'GBP' and Date_c = :ForDate",
                 binds: [Base: 'XXX', ForDate: today() ])
// Will be updating the queried rows, so use queryRows()
for (txn in adf.util.queryRows(select:'Id,Cleared_c,Currency_c,Amount_c,Date_c', 
                                 from: 'Transaction_c',
                                where: "Cleared_c = 'N'")) {
  def rate = 1
  // If transaction currency is different than GBP, lookup historical
  // exchange rate for the date of the transaction to convert the 
  // transaction currency into GBP
  if (txn.Currency_c != 'GBP') {
    // Set any bind variables to new values for current loop iteration
    setBindVariable(rateVO,'Base',txn.Currency_c)
    setBindVariable(rateVO,'ForDate',txn.Date_c)
    // Execute the same view object with the new bind variable values
    rateVO.executeQuery()
    rate = rateVO.first()?.Rate_c
  }
  if (rate) {
    txn.Cleared_c = 'Y'
    // Multiply original txn amount by rate and round to 2 decimal places 
    txn.AmountInGBP_c = (txn.Amount_c * rate as Double).round(2)  
  }
}