A SQL構造化置換APIリファレンス

この項ではよく使用されるいくつかの構造化置換APIコールとその詳細について説明します。

すべての構造化置換APIのリファレンスは、Oracle Data Integrator Java置換APIリファレンスを参照してください。

図A-1 SQL構造化置換APIオブジェクトUMLダイアグラム

図A-1の説明
「図A-1 SQL構造化置換APIオブジェクトUMLダイアグラム」の説明

この図を簡略化すると次のようになります。

図A-2 SQL構造化置換APIオブジェクト(簡易バージョン)

図A-2の説明が続きます
「図A-2 SQL構造化置換APIオブジェクト(簡易バージョン)」の説明

組込み変数名

コード例では次の組込み変数が使用されています。

  • INSERT (SqlInsertStatement) - ターゲットIKMによって作成されるトップレベルの挿入文オブジェクト。

  • QUERY (SqlQuery) - ターゲットまたはステージング表にロードするデータの抽出に使用されるトップレベル・ソース問合せ。

  • ATTR (MapAttribute) - テンプレート(存在する場合)の処理時にスコープ内にある現在のソース属性。

  • physicalNode (MapPhysicalNode) - KMが割り当てられている物理マッピング・ノード。

  • component (IMapComponent) - KMが割り当てられている物理ノードに対応する論理マッピング・コンポーネント。

A.1 SqlInsertStatement.getColumnList()

使用方法

public List<Column>getColumnList()

説明

このメソッドは、挿入文のターゲット列オブジェクトのリストを取得するために使用します。各列には、ターゲット列の名前、データ型、およびサイズに関する情報が含まれています。また、この列のロードに使用した問合せ選択アイテムがわかります。

例1

IKM Oracle挿入をベースKMとして持つIKMにテスト・タスクが設定されています。

KMタスク・ローカルgroovy変数定義スクリプト:
def colList = INSERT.getColumnList()
colListStr = ''

for (Column col : colList) {
  if (colListStr.length() != 0) colListStr += ",\n"
  colListStr += col.getTable().getQualifier() + '.' + col.getTable().getName()
  colListStr += " /* Will be loaded from " + (col.getSourceSelectItem()  == null ? "unknown" : col.getSourceSelectItem()) + " */"
}
KMターゲット・コマンド・テキスト:

Generated column list string = $[colListStr]

生成されたコード:
Generated column list string =
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."Stock_Name" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."Stock_Symbol" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."Stock_Type" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."Industry_Type" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."SP_Rating" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."Company_Name" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."Registered_Address" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."Registered_City" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."Registered_State" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."Postal_Code" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."Registered_County" */,
COMPKM_TEST_TGT_SCHEMA.Stock_Dim /* Will be loaded from STOCK_SRC."FaceValue" */

例2:

例のように設定するには、「オブジェクト」アコーディオンの下にある「セキュリティ」ナビゲータで「属性」オブジェクト用の新しいフレックスフィールドを設定します。新しいフレックスフィールドの名前は「ATTR_SUFFIX」です。また、ソース・データストア・モデルの3つの属性に、デフォルト以外の値が設定されています。値は、「_KEY1」、「_KEY2」および「_KEY3」です。

また、「ADD_SUFFIXES」という新しいブールKMオプションがテストKMに追加され、テスト・マッピングでターゲット・ノードに割り当てられているKMインスタンス用の新しいオプションの値はtrueに設定されます。IKM Oracle挿入をベースKMとして持つIKMにテスト・タスクが設定されています。

KMタスク・ローカルgroovy変数定義スクリプト:
def colList = INSERT.getColumnList()
colListStr = ''
addSuffixes = physicalNode.getKMOptionValueBoolean("ADD_SUFFIXES")
for (Column col : colList) {
  if (colListStr.length() != 0) colListStr += ",\n"
  attrs = col.getSourceSelectItem().getSourceAttributes()
  String suffix = "";
  if (addSuffixes && attrs != null && attrs.size() > 0) {
    suffix = attrs.get(0).getFlexFieldValue("ATTR_SUFFIX")
  }
  colListStr += col.getTable().getQualifier() + '.' + col.getTable().getName() + "." + '\"' + col.getUnquotedName() + suffix + '\"'
}
KMターゲット・コマンド・テキスト:

Column List string with suffixes from source flex fields: $[colListStr]

生成されたコード:
Column List string with suffixes from source flex fields:
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."Stock_Name",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."Stock_Symbol_CUSTOM_KEY2",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."Stock_Type",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."Industry_Type_CUSTOM_KEY3",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."SP_Rating",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."Company_Name_CUSTOM_KEY1",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."Registered_Address",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."Registered_City",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."Registered_State",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."Postal_Code",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."Registered_County",
COMPKM_TEST_TGT_SCHEMA.Stock_Dim."FaceValue"

A.2 SqlInsertStatement.getQuery()

使用方法

public SqlQuery getQuery()

説明

このメソッドは、ターゲットIKMまたはLKM APIオブジェクトからメイン・ソース問合せオブジェクトを取得するために使用します。SqlQueryオブジェクトには、SQL問合せを作成するために必要なすべてのメタデータが含まれています。問合せは再帰的に定義されるため、問合せオブジェクトが所有するFromClauseオブジェクトに、最上位問合せの副問合せを表すSqlQueryオブジェクトが含まれる可能性があります。

SQL挿入KMの最上位INSERTオブジェクトのgetQuery() methodの戻り値は、組込みQUERY変数の値と同じである必要があります。簡易テストのために、次のようなタスクを作成します。

KMタスク・ローカルgroovy変数定義スクリプト:

sourceQuery = INSERT.getQuery() queryEqualsString = (sourceQuery.equals(QUERY) ? "equal to" : "not equal to")

KMターゲット・コマンド:

INSERT.getQuery()から組込みQUERY変数への戻り値は$[queryEqualsString]です。

生成されたコード:
-- The first subquery is:
SELECT 
  EMP.EMP_NO AS EMP_NO ,
  EMP.LAST_NAME AS LAST_NAME ,
  EMP.FIRST_NAME AS FIRST_NAME ,
  EMP.DEPT_ID AS DEPT_ID   
FROM /* Top-level from clause */  
  ODI_SRC.EMP@NEXTGEN_TEST_ORACLE_SRC EMP  
GROUP BY
  EMP.EMP_NO,EMP.LAST_NAME,EMP.FIRST_NAME,EMP.DEPT_ID 
-- The source mapping physical node for the subquery is JOIN1  

A.3 SqlQuery.getSubqueries ()

使用方法

public List<SqlQuery>getSubqueries ()

説明

このメソッドは、問合せによって定義される副問合せのセットを取得するために使用します。このメソッドは第1レベルの副問合せのみを返します。返される各副問合せには、同じメソッドを使用して取得できる他の副問合せが含まれる可能性もあります。

例では、副問合せが見つかった場合はそれを取得し、第1副問合せの副問合せテキストが表示されます。

KMタスク・ローカルgroovy変数定義スクリプト:
subqueries = QUERY.getSubqueries()
subquery = null;
if (subqueries != null && subqueries.size() > 0) {
  subquery = QUERY.getSubqueries().get(0)
} else {
  odiRef.warn("No subquery found")
}
println("In task groovy, subquery is " + subquery)
subquerySourceNodeName = (subquery == null ? "unknown" : subquery.getMapPhysicalNode().getName())
println("In task groovy, subquerySourceNodeName is" + subquerySourceNodeName)
KMターゲット・コマンド:

第1副問合せは、{#IF ($[subquery] != null) #} $[subquery.getText()] {#ELSE#} not found {# ENDIF #}です。副問合せのソース・マッピング物理ノードは、 $[subquerySourceNodeName]です。

生成されたコード:
-- The first subquery is:
SELECT 
  EMP.EMP_NO AS EMP_NO ,
  EMP.LAST_NAME AS LAST_NAME ,
  EMP.FIRST_NAME AS FIRST_NAME ,
  EMP.DEPT_ID AS DEPT_ID   
FROM /* Top-level from clause */  
  ODI_SRC.EMP@NEXTGEN_TEST_ORACLE_SRC EMP  
GROUP BY
  EMP.EMP_NO,EMP.LAST_NAME,EMP.FIRST_NAME,EMP.DEPT_ID 
-- The source mapping physical node for the subquery is JOIN1  

A.4 SqlInsertStatement.getTargetTable ()

使用方法

public Table getTargetTable() ()

説明

このメソッドは、ターゲット表を表す置換APIオブジェクトを取得するために使用します。戻りタイプは「表」であり、ターゲット表の名前と特性を取得するためのメソッドが提供されます。

例では、表を作成するためのSQL DDL CREATE文が生成されます。

KMタスク・ローカルgroovy変数定義スクリプト:
table = INSERT.getTargetTable()
tableName = table.getCreationName()
tableQualifier = physicalNode.getLocation() == null ? null : physicalNode.getLocation().getName();
odiRuntimeAccessName = OdiRef.getOdiGeneratedAccessName("TARG_NAME", physicalNode, "A");
tableAlias = component.getAlias();
tgtColList = { 
  def cols = component.getAttributes();
  String result = ""
  def first = true
  for (col in cols) {
    if (!first) result += ",\n"
    result += col.getSQLAccessName(false, "") + " " + MappingUtils.getDdlDataType(col.getBoundObject());
    first = false
  }
  return result
}
KMターゲット・コマンド:
create table $[odiRuntimeAccessName]
(
  $[tgtColList.call()]
)
生成されたコード:
create table COMPKM_TEST_TGT_SCHEMA."Stock_Dim"
(
  "Stock_Key_PK" NUMBER(30),
"Split_Key" NUMBER(30),
"Stock_Name" VARCHAR2(50),
"Stock_Symbol" VARCHAR2(50),
"Stock_Type" VARCHAR2(50),
"Industry_Type" VARCHAR2(50),
"SP_Rating" VARCHAR2(50),
"Company_Name" VARCHAR2(50),
"Registered_Address" VARCHAR2(50),
"Registered_City" VARCHAR2(50),
"Registered_State" VARCHAR2(50),
"Postal_Code" VARCHAR2(50),
"Registered_County" VARCHAR2(50),
"FaceValue" NUMBER(30)
)

A.5 SqlQuery.getFromList ()

使用方法

public List<FromClause> getFromList()

説明

このメソッドは、SQL問合せオブジェクトのFROM句を表すFROM句構造のリストを取得するために使用します。個別の各FROM句は、なんらかのソース表またはインライン・ビューを表します。基本的には、3つのタイプのFROM句があります。
  • 単純な表の参照

  • 副問合せの参照

  • ANSI JoinTableの参照

ANSI結合表なしに単純な表または副問合せを使用する場合、WHERE句で表間の結合関係を指定する必要があります。JoinTableを使用する場合は、ON句が含まれます。ON句には、メソッドJoinTable.getPredicate()またはJoinTable.getPredicateText()を使用してアクセスします。副問合せを使用する場合とJoinTableを使用する場合はいずれも、副問合せの標準のFROMリストまたはANSI結合副問合せソースを表す、ネストされた問合せを使用できます。

例では、FromClause.getSourceTables()コールを使用して、メインFROM句オブジェクトを取得してすべてのソース表のリストを導出します。

KMタスク・ローカルgroovy変数定義スクリプト:
sourceTables = QUERY.getFromList().get(0).getSourceTables()
sourceTableNames = ''
for (sourceTable in sourceTables) {
  if (sourceTableNames.length() > 0) sourceTableNames += ", ";
  sourceTableNames += sourceTable.getName();
}
KMターゲット・コマンド:

The source tables are: $[sourceTableNames]

生成されたコード:

The source tables are: EMP, DEPT

A.6 SqlQuery.getSelectList ()

使用方法

public List<ISelectItem> getSelectList()

説明

このメソッドは、SQL問合せオブジェクトに存在する選択アイテムのリストを取得するために使用します。各アイテムは、IselectItemのインタフェース・インスタンスによって表されます。ISelectItemの実装はArrayExpression、StringExpressionおよびCorrelatedSubqueryです。タイプはjavaまたはgroovyの「instanceof」コールを使用して決定されます。ArrayExpressionはマッピング属性が所有する式を表し、参照先の副問合せを使用した複雑な式である可能性があります。StringExpressionは単純な文字列式を表します。CorrelatedQueryオブジェクトは、問合せの選択アイテムとして使用できる列と行を返す副問合せである、相関問合せ(スカラー副問合せとも呼ばれます)を表します。

例では、各選択アイテムのタイプとテキストを印刷します。

KMタスク・ローカルgroovy変数定義スクリプト:
selectList = QUERY.getSelectList()
selectListString = ''
index = 0;
for (item in selectList) {
  if (selectListString.length() > 0) selectListString += ",\n"
  selectListString += sprintf('item %1$d: type=%2$s text=%3$s', index++, item.getClass().getName(), item.toString()) 
}
KMターゲット・コマンド:

Select list string is:{#NL#} $[selectListString]

生成されたコード:
Select list string is:
item 0: type=oracle.odi.mapping.generation.ArrayExpression text=EMP_1.EMP_NO,
item 1: type=oracle.odi.mapping.generation.ArrayExpression text=EMP_1.LAST_NAME,
item 2: type=oracle.odi.mapping.generation.ArrayExpression text=EMP_1.FIRST_NAME,
item 3: type=oracle.odi.mapping.generation.ArrayExpression text=DEPT.DEPT_NAME 

A.7 FromClause.getJoinTable ()

使用方法

public JoinTable getJoinTable ()

説明

このメソッドは、FROM句オブジェクトがANSI結合を表している場合に、FROM句オブジェクトからANSI結合表を取得するために使用します。JoinTableオブジェクトは、左および右の結合ソース(単純な表またはその他の結合表が可能)のホルダーです。これはまた、結合タイプ(内部、左外部、右外部など)と結合条件式も保持します。

例では、結合表の結合タイプ、右および左のソース、およびON句(存在する場合)が印刷されます。

KMタスク・ローカルgroovy変数定義スクリプト:
joinTable = QUERY.getFromList().get(0).getJoinTable()
joinTableStr = ''
if (joinTable != null) {
  joinTableStr = sprintf('type=%1$s\nleft text=%2$s\nright text=%3$s\njoin condition=%4$s', 
    joinTable.getJoinType(), joinTable.getLeftText(), joinTable.getRightText(), joinTable.getPredicateText()) 
} else {
  joinTableStr = 'No join table found'
}
KMターゲット・コマンド:

Join table information: $[joinTableStr]

生成されたコード:
Join table information:
type=INNER
left text=(
SELECT 
  EMP.EMP_NO AS EMP_NO ,
  EMP.LAST_NAME AS LAST_NAME ,
  EMP.FIRST_NAME AS FIRST_NAME ,
  EMP.DEPT_ID AS DEPT_ID   
FROM 
  ODI_SRC.EMP@NEXTGEN_TEST_ORACLE_SRC EMP  
GROUP BY
  EMP.EMP_NO,EMP.LAST_NAME,EMP.FIRST_NAME,EMP.DEPT_ID 
  ) EMP_1
right text=ODI_SRC.DEPT@NEXTGEN_TEST_ORACLE_SRC DEPT
join condition=EMP_1.DEPT_ID = DEPT.DEPT_ID 

A.8 FromClause.getSourceTables ()

使用方法

public List<Table> getSourceTables ()

説明

このメソッドは、FROM句オブジェクトに含まれるすべての単純ソース表のリストを取得するために使用します。結合表または副問合せ参照は含まれません。

次の例では、マッピング内の各単純ソース表の表名および論理スキーマの場所を示します。

KMタスク・ローカルgroovy変数定義スクリプト:
fromClause = QUERY.getFromList().get(0)
sourceTables = fromClause.getSourceTables()
sourceTableList = '';
context = physicalNode.getContext();
for (sourceTable in sourceTables) {
  sourceTableLocation = sourceTable.getBoundDatastore().getModel().getObjectLocation(context);
  sourceTableList += sprintf('Table name=%1$s, logical schema=%2$s\n', sourceTable.getName(), sourceTableLocation.getLogicalSchema().getName())
}
KMターゲット・コマンド:

Source table list: $[sourceTableList]

生成されたコード:
Source table list:
Table name=EMP, logical schema=NEXTGEN_TEST_ORACLE_SRC
Table name=DEPT, logical schema=NEXTGEN_TEST_ORACLE_SRC 

A.9 FromClause.getTableQuery ()

このメソッドFromClause.getTableQuery ()には、次のメソッドが含まれています。

  • JoinTable.getLeftTableQueryRef ()

  • FromClause.getRightTableQueryRef ()

使用方法

public TableQueryReference getTableQuery ()
public TableQueryReference getLeftTableQueryRef ()
public TableQueryReference getRightTableQueryRef ()

説明

これらのメソッドは、FROM句の表問合せオブジェクトを取得するため、または表問合せを含むJoinTableオブジェクトから表問合せオブジェクトを取得するために使用します。表問合せは、副問合せオブジェクトまたは単純表のホルダーです。使用するKMによっては、FROM句自身によってTableQueryが含まれる場合や、結合表オブジェクトの右または左側にTableQueryが含まれる場合があります。

例では、最初のFROM句にJoinTableが存在するかどうかを確認し、存在する場合、左側に副問合せがあれば、結合表の左側から副問合せを取得します。

KMタスク・ローカルgroovy変数定義スクリプト:
fromClause = QUERY.getFromList().get(0)
fromClauseHasJoinTable = (fromClause.getJoinTable() == null ? "does not have" : "has") + " a join table"
tableQueryRef = QUERY.getFromList().get(0).getJoinTable().getLeftTableQueryRef()
query = null
subqueryText = null
if (tableQueryRef != null) {  // Not every FROM clause has a table query object, so protect against null.
  query = tableQueryRef.getQuery()
  if (query != null) {
    subqueryText = query.getText()
  }
}
KMターゲット・コマンド:
From clause $[fromClauseHasJoinTable]
{#IF $[subqueryText] != null #}
subquery text:
$[subqueryText]
{# ELSE #}
No subquery text found.
{# ENDIF #}
生成されたコード:

From clause has a join table subquery text:

SELECT 
  EMP.EMP_NO AS EMP_NO ,
  EMP.LAST_NAME AS LAST_NAME ,
  EMP.FIRST_NAME AS FIRST_NAME ,
  EMP.DEPT_ID AS DEPT_ID   
FROM 
  ODI_SRC.EMP@NEXTGEN_TEST_ORACLE_SRC EMP  
GROUP BY
  EMP.EMP_NO,EMP.LAST_NAME,EMP.FIRST_NAME,EMP.DEPT_ID 

A.10 ArrayExpression.getTemplate()

使用方法

public String getTemplate ()

説明

このメソッドは、ArrayExpressionオブジェクトのコード生成テンプレートを取得します。ArrayExpressionは、ネストされた式を処理できる特殊なコード生成式オブジェクトです。たとえば、ODIマッピングに連続する複数の式コンポーネントが存在し、それぞれの式が前の式コンポーネントの式属性を参照している場合、最終的な問合せにネストされた式が存在することになります。たとえば、最初の式EXPRに属性EMPSALがあり、その式が"EMP.SAL + 100"であるとします。さらに、次の式コンポーネントに"EXPR.EMPSAL – 50"のような式があるとします。この場合、抽出問合せで使用される最終的な式は、"(EMP.SAL + 100) – 50"になります。ArrayExpressionオブジェクトは、テンプレート・テキスト内に子オブジェクトへのテンプレート参照が存在する最上位テンプレートを使用することによって、これを処理します。テキストのテンプレート参照の例は、"@{R0}"などです。これは、子ハッシュ表のキーが"R0"である子式を参照します。各子オブジェクトには、単純な文字列式、または別のArrayExpression (複数レベルのネスト用)、またはソース属性を指定できます。getTemplate()メソッドは、ArrayExpressionテキストの作成に使用するテキストのテンプレートを返します。

例では、ソース問合せ内のすべての選択リスト・アイテムをループし、ArrayExpressionオブジェクトとして実装されたものを見つけ、テキスト全体とテンプレート・テキストを表示します。

KMタスク・ローカルgroovy変数定義スクリプト:

selectList = QUERY.getSelectList()
arrayExprListString = ''
for (selectItem in selectList) {
  ArrayExpression arrayExpr = selectItem.getArrayExpression()
  if (arrayExpr != null) {
    if (arrayExprListString.length() != 0) arrayExprListString += '\n';
    arrayExprListString += sprintf('text=%1$s, template=%2$s', arrayExpr.getText(), arrayExpr.getTemplate())
  }
}

KMターゲット・コマンド:

Here is the list of ArrayExpression templates:$[arrayExprListString]

生成されたコード:
Here is the list of ArrayExpression templates:
text=(EMP.EMP_NO + 100)*2, template=(@{R0} + 100)*2
text=EMP.LAST_NAME, template=@{R0}
text=EMP.FIRST_NAME, template=@{R0}
text=(EMP.FIRST_NAME || EMP.LAST_NAME), template=@{R0}
text=DEPT.DEPT_NAME, template=@{R0} 

A.11 ArrayExpression.getChildMap()

使用方法

public Map<String,Object> getChildMap ()

説明

このメソッドは、このArrayExpressionオブジェクトが所有している子オブジェクトを含むハッシュ・マップを取得します。ハッシュ・キーは、前のメソッドで説明したように、ArrayExpressionテンプレートで使用される一致キーです。

例では、ソース問合せ内のすべての選択リスト・アイテムをループし、ArrayExpressionオブジェクトとして実装されたものを見つけ、テキスト全体とテンプレート・テキストを表示します。

KMタスク・ローカルgroovy変数定義スクリプト:
selectList = QUERY.getSelectList()
arrayExprListString = ''
for (selectItem in selectList) {
  ArrayExpression arrayExpr = selectItem.getArrayExpression()
  if (arrayExpr != null) {
    if (arrayExprListString.length() != 0) arrayExprListString += '\n';
    arrayExprListString += sprintf('ArrayExpression text=%1$s, template=%2$s', arrayExpr.getText(), arrayExpr.getTemplate())
    childMap = arrayExpr.getChildMap()
    for (childKey in childMap.keySet()) {
      arrayExprListString += sprintf('\n\tChild item: key=%1$s, object=%2$s', childKey, childMap.get(childKey).toString())
    }
  }
} 
KMターゲット・コマンド:

Here is the ArrayExpression list with child objects:$[arrayExprListString]

生成されたコード:
Here is the ArrayExpression list with child objects:
ArrayExpression text=(EMP.EMP_NO + 100)*2, template=(@{R0} + 100)*2
	Child item: key=R0, object=EMP.EMP_NO
ArrayExpression text=EMP.LAST_NAME, template=@{R0}
	Child item: key=R0, object=EMP.LAST_NAME
ArrayExpression text=EMP.FIRST_NAME, template=@{R0}
	Child item: key=R0, object=EMP.FIRST_NAME
ArrayExpression text=(EMP.FIRST_NAME || EMP.LAST_NAME), template=@{R0}
	Child item: key=R0, object=EMP.FIRST_NAME || EMP.LAST_NAME
ArrayExpression text=DEPT.DEPT_NAME, template=@{R0}
	Child item: key=R0, object=DEPT.DEPT_NAME