SysDa クラスを使用したデータへのアクセス

Note

コミュニティの関心グループが Yammer から Microsoft Viva Engage に移行されました。 Viva Engage コミュニティに参加し、最新のディスカッションに参加するには、「 Finance and Operations Viva Engage Community へのアクセスを要求する 」フォームに入力し、参加するコミュニティを選択します。

この記事では、SysDa アプリケーション プログラミング インターフェイス (API) を使用して拡張可能なクエリを作成する方法について説明します。

拡張可能な SysDa API では、X++ で使用できるほとんどすべてのデータアクセス可能性が提供されます。 実際、API は X++ コンパイラによって生成されるコードのラッパーです。 したがって、たとえば QueryRun オブジェクトの使用とは異なり、SysDa クラスを使用してもオーバーヘッドは発生しません。 さらに、データ アクセス ステートメントの正確性を確保する責任があります。 たとえば、グローバルな一意識別子 ( GUID) を整数と比較する where 句を作成します。 X++ コンパイラは、この句をエラーとして診断します。

SysDa API には、カスタムクエリを作成するための広範な API セットが含まれています。 小さな種類のセットが主なクエリアクティビティを駆動します。

  • 次を選択します: SysDaQueryObjectSysDaSearchObject、および SysDaSearchStatement
  • 次を更新します: SysDaUpdateObject および SysDaUpdateStatement
  • 次を挿入します: SysDaInsertObject および SysDaInsertStatement
  • 次を削除します: SysDaQueryObjectSysDaDeleteObject、および SysDaDeleteStatement

次のセクションでは、クエリのタイプの例と、それがサポートするカスタマイズについて説明します。 この例では、TestTable という名前のテーブルを使用します。 このテーブルには、 stringField という名前の文字列フィールドと intField という名前の整数フィールドの 2 つのフィールドがあります。

クエリの選択

選択クエリを実行するには、次の手順に従います。

  1. 指定されたレコードを含むテーブル インスタンスを指定する SysDaQueryObject オブジェクトを作成して構成します。
  2. Sysdasearchobject オブジェクトを作成し、SysDaQueryObject オブジェクトをコンストラクターに渡します。
  3. Sysdasearchobject オブジェクトを SysDaSearchStatement.findNext() メソッドに渡すことで、クエリの結果を繰り返します。

次の例では、intField<= 5 である TestTable のすべての行を検索します。

// t is the table buffer that will hold the result.
TestTable t;

// Create the query.
var qe = new SysDaQueryObject(t);

// Add clauses to the query. First the projection.
var s = qe.projection()
    .add(fieldStr(TestTable, intField))
    .add(fieldStr(TestTable, stringField));

// At this point the query is:
// intField, stringField FROM TestTable

// Add a where clause to include rows where intField is <= 5.
qe.WhereClause(new SysDaLessThanOrEqualsExpression(
    new SysDaFieldExpression(t, fieldStr(TestTable, intField)),
    new SysDaValueExpression(5)));

// Now the query is:
// intField, stringField FROM TestTable WHERE (TestTable.intField<= 5)

// Order the results by intField.
qe.OrderByClause().addDescending(fieldStr(TestTable, intField));

// Now the query is:
// intField, stringField FROM TestTable ORDER BY intField DESC WHERE (TestTable.intField<= 5)

var so = new SysDaSearchObject(qe);
var ss = new SysDaSearchStatement();

// Enumerate the designated values by using ss.
while (ss.findNext(so))
{
    info(t.stringField);
}

または、Fluent な方法で SysDaQueryObject を構築する、SysDaQueryObjectBuilder を使用できます。

SysDaQueryObjectBuilder は、4 つの JOIN 句すべてサポートしています。

  • INNER
  • OUTER
  • EXISTS
  • NOT EXISTS JOIN

次の 5 つの集計関数がすべてサポートされています。

  • COUNT
  • 合計
  • AVG
  • MIN
  • MAX

WHERE 句および複数の WHERE 句は ANDed をサポートします。

次の 7 つの比較式がすべてサポートされています。

  • ==
  • <>
  • >
  • >=
  • <
  • <=
  • LIKE
  • IN

ORDER BY 句をサポートします。

GROUP BY 句をサポートします。

これは、すべての 16 ヒントをサポートしています:

  • firstOnly1
  • firstOnly10
  • firstOnly100
  • firstOnly1000
  • firstFast
  • リバース
  • forUpdate
  • noFetch
  • forceSelectOrder
  • forceNestedLoop
  • forceLiterals
  • forcePlaceholders
  • repeatableRead
  • optimisticLock
  • pessimisticLock
  • generateOnly

次の例では、SysDaQueryObject を構築する 2 つの方法を示します。

SysDaQueryObjectBuilder::from(exampleTable)
    .firstOnly()
    .innerJoin(exampleJoinedTable)
    .where(exampleTable, fieldStr(ExampleTable, ExampleJoinedTableExampleId)).isEqualTo(exampleJoinedTable, fieldStr(ExampleJoinedTable, ExampleId))
    .where(exampleTable, fieldStr(ExampleTable, ExampleNumber)).isEqualToLiteral(0)
    .toSysDaQueryObject();
var exampleTableQueryObject = new SysDaQueryObject(exampleTable);
var exampleJoinedTableQueryObject = new SysDaQueryObject(exampleJoinedTable);
exampleTableQueryObject.firstOnlyHint = SysDaFirstOnlyHint::FirstOnly1;
exampleTableQueryObject.joinClause(SysDaJoinKind::InnerJoin, exampleJoinedTableQueryObject);
exampleJoinedTableQueryObject.whereClause(new SysDaAndExpression(
    new SysDaEqualsExpression(
        new SysDaFieldExpression(exampleTable, fieldStr(ExampleTable, ExampleJoinedTableExampleId)),
        new SysDaFieldExpression(exampleJoinedTable, fieldStr(ExampleJoinedTable, ExampleId))),
    new SysDaEqualsExpression(
        new SysDaFieldExpression(exampleTable, fieldStr(ExampleTable, ExampleNumber)),
        new SysDaValueExpression(0))));

SysDaQueryExpression を使用すると、OR などの式を有効にできます。

次の例では、OR を使用して SysDaQueryObject を構築します。

SysDaQueryObjectBuilder::from(exampleTable)
    .wherever(new SysDaOrExpression(
        new SysDaEqualsExpression(
            new SysDaFieldExpression(exampleTable, fieldStr(ExampleTable, ExampleNumber)),
            new SysDaValueExpression(0)),
        new SysDaEqualsExpression(
            new SysDaFieldExpression(exampleTable, fieldStr(ExampleTable, ExampleNumber)),
            new SysDaValueExpression(0))))
    .toSysDaQueryObject();

明細書の更新

update ステートメントを実行するには、次の手順に従います。

  1. SysDaUpdateObjectオブジェクトを作成および構成します。
  2. SysDaUpdateObject オブジェクトを SysDaUpdateStatement.execute() メソッドに渡してデータを更新します。 更新によってデータベース内のデータが変更されるため、ttsbegin ステートメントと ttscommit ステートメントで実行する呼び出しをラップします。

次の例では、intField50 のすべての行について、 = を "fifty" に更新します。

TestTable t;

// Create an update query to find rows where intField = 50.
var uo = new SysDaUpdateObject(t);

// Set stringField to "fifty".
uo.settingClause()
    .add(fieldStr(TestTable, stringField), new SysDaValueExpression("fifty"));

// At this point the update statement is:
// UPDATE_RECORDSET TestTable SETTING stringField=fifty

uo.whereClause(new SysDaEqualsExpression(
    new SysDaFieldExpression(t, fieldStr(TestTable, intField)),
    new SysDaValueExpression(50)));

// Now the update statement is:
// UPDATE_RECORDSET TestTable SETTING stringField=fifty WHERE (TestTable.intField == 50)

// Update the rows.
ttsbegin;
    new SysDaUpdateStatement().update(uo);
ttscommit;

// Verify the results of the update query.
TestTable t1;
select intField, stringField from t1 where t1.intField == 50;
info("Updated value is: " + t1.stringField);
// Output is: "Updated value is: fifty".

明細書の挿入

insert ステートメントを実行するには、次の手順に従います。

  1. SysDaInsertObject オブジェクトを作成および構成して、挿入中に更新されるフィールドを指定します。
  2. 挿入する行のソースを指定する SysDaQueryObject オブジェクトを作成および構成します。 SysDaQueryObject.予測() のフィールドの順序は、SysDaInsertObject.fields() のフィールドの順序と一致している必要があります。
  3. SysDaQueryObject オブジェクトを、SysDaInsertObject オブジェクトに割り当てます。
  4. 新しい行を挿入するにはSysDaInsertObject オブジェクトを SysDaInsertStatement.executeQuery() メソッドに渡します。

次の例では、行を intField = 40stringField = "en-us" を TestTable に挿入します。

TestTable t;

// Specify the fields in the new row.
var insertObject = new SysDaInsertObject(t);
insertObject.fields()
    .add(fieldStr(TestTable, stringField))
    .add(fieldStr(TestTable, intField));

// At this point the insert statement is:
// INSERT_RECORDSET TestTable(stringField, intField) SELECT

// Retrieve the data to insert from the LanguageTable by using a query.
LanguageTable source;
var qe = new SysDaQueryObject(source);

var s1 = qe.projection()
    .Add(fieldStr(LanguageTable, LanguageId))
    .AddValue(40);

// The query statement is:
// LanguageId, 40 FROM LanguageTable

qe.WhereClause(new SysDaEqualsExpression(
        new SysDaFieldExpression(source, fieldStr(LanguageTable, LanguageId)),
        new SysDaValueExpression("en-us")));

// Now the query is:
// LanguageId, 40 FROM LanguageTable WHERE (LanguageTable.LanguageId == en-us)

// Assign the query to the insert statement.
insertObject.query(qe); 

// The insert statement is now:
// INSERT_RECORDSET TestTable(stringField, intField) SELECT LanguageId, 40 FROM LanguageTable WHERE (LanguageTable.LanguageId == en-us)

var insertStmt = new SysDaInsertStatement();
ttsbegin;
    insertStmt.insert(insertObject);
ttscommit;

// Verify the results of the insert query.
TestTable t1;
select * from t1 where t1.stringField == "en-us";
info(any2Str(t1.intField) + ":" + t1.stringField); 
// The output is "40:en-us".

明細書の削除

delete ステートメントを実行するには、次の手順に従います。

  1. Sysdaqueryobject オブジェクトを作成および構成して、削除する行を指定します。
  2. SysDaDeleteObject オブジェクトを作成し、SysDaQueryObject オブジェクトをコンストラクターに渡します。
  3. 行を削除するには SysDaDeleteObject オブジェクトを SysDaDeleteStatement.executeQuery() メソッドに渡します。

次の例では、intField が偶数である行を削除します。

TestTable t;

// Build the query that specifies which rows to delete.
var qe = new SysDaQueryObject(t);

var s = qe.projection()
    .add(fieldStr(TestTable, intField));

// At this point the query is:
// intField FROM TestTable

// Delete rows where intField is even.
qe.WhereClause(new SysDaEqualsExpression(
    new SysDaModExpression(
    new SysDaFieldExpression(t, fieldStr(TestTable, intField)),
    new SysDaValueExpression(2)),
    new SysDaValueExpression(0)));

// Now the query is:
// intField FROM TestTable WHERE ((TestTable.intField MOD 2) == 0)

var ds = new SysDaDeleteStatement();
var delobj = new SysDaDeleteObject(qe);

// The deletion statement, from the SysDaDeleteObject, is:
// DELETE_FROM intField FROM TestTable WHERE ((TestTable.intField MOD 2) == 0)

ttsbegin;
    ds.delete(delobj);
ttscommit;

info("Number of rows deleted: " + any2Str(t.RowCount()));

IN キーワード

SysDaInExpression クラスは、リストの値に基づいて行をフィルター処理します。 これは、Array クラスから派生した厳密に型指定されたコンテナーです。 次の例では、 TransType 値が Sales または Cust のいずれかに等しい行をフィルター処理します。

CustTrans custTrans;
SysDaQueryObject qe = new SysDaQueryObject(custTrans);
Array array = new Array(Types::Integer);

array.value(1, LedgerTransType::Sales);
array.value(2, LedgerTransType::Cust);

qe.firstOnlyHint = SysDaFirstOnlyHint::FirstOnly10;
qe.whereClause(new SysDaInExpression(
    new SysDaFieldExpression(custTrans, fieldStr(CustTrans, TransType)),
    new SysDaValueExpression(array.pack())));

SysDaSearchObject so = new SysDaSearchObject(qe);
SysDaSearchStatement ss = new SysDaSearchStatement();

while (ss.findNext(so))
{
    info(strFmt('%1 - %2', custTrans.AccountNum, custTrans.TransType));
}

//so.toString: WHILE SELECT FIRSTONLY10 FROM CustTrans WHERE (CustTrans.TransType in System.Object[])

SysDa クエリは複数の句をサポートします。

  • whereClauseSysDaQueryExpression から継承するオブジェクトから where 句を構築します。 たとえば、 SysDaEqualsExpressionSysDaNotEqualsExpressionSysDaLessThanExpression などがあります。 完全な一覧を表示するには、アプリケーション エクスプローラーでフィルター処理します。
  • orderByClause
  • groupByClause
  • joinClauseKind 付き joinClause
  • joinedQuery
  • settingClause

Troubleshooting

作成しているステートメントを表示するには、SysDaQueryObject、SysDaUpdateObjectSysDaInsertObject、および SysDaQueryObject オブジェクトの toString() メソッドを使用します。