SQL 受信アダプタの使用法
この章では、Ensemble SQL 受信アダプタ (EnsLib.SQL.InboundAdapterOpens in a new tab) のデフォルトの動作、およびプロダクションでのこのアダプタの使用法について説明します。以下のトピックについて説明します。
-
どの行が既に処理されているのかを“忘れる”ようにするアダプタのリセット方法 (開発時に役立つタスク)
全般的な動作
まず、アダプタに対して指定する詳細について理解しておくと役立ちます。EnsLib.SQL.InboundAdapterOpens in a new tab クラスには、以下のような項目の指定に使用する実行時設定が用意されています。
-
アダプタが新規入力をチェックする頻度を制御する、ポーリング間隔
-
アダプタの接続先である外部データ・ソース
-
必要に応じてデータ・ソースにユーザ名とパスワードを提供する Ensemble 資格情報の ID
-
実行する SQL クエリ
-
クエリで使用するオプションのパラメータ
通常、受信 SQL アダプタ (EnsLib.SQL.InboundAdapterOpens in a new tab) は、クエリを定期的に実行し、結果セットの行を反復し、関連するビジネス・サービスに 一度に 1 行ずつ渡します。ユーザが作成および構成するビジネス・サービスでは、この行を使用してプロダクションの他の部分と通信します。さらに具体的に説明します。
-
アダプタは、定期的にその OnTask() メソッドを実行します。このメソッドは、指定されたクエリを実行します。ポーリング間隔は CallInterval 設定によって決定されます。
-
クエリが行を返す場合は、アダプタが結果セットの行を反復し、行ごとに以下の手順を実行します。
-
この行が既に処理されているものの、変更されていない場合は、無視します。
特定の行が既に処理されているかどうかを判別するために、アダプタは KeyFieldName 設定の情報を使用します。この章の “新規行のみの処理” を参照してください。
-
この行が既に処理されており (KeyFieldName 設定で処理済みと識別)、エラーが発生した場合は、次回再起動するまでこの行を無視します。
-
それ以外の場合は、アダプタが EnsLib.SQL.SnapshotOpens in a new tab クラスのインスタンスを構築し、行のデータをインスタンスに入れます。このインスタンスがスナップショット・オブジェクトです。このオブジェクトの詳細は、この章の “デフォルトのスナップショット・オブジェクトの使用法” を参照してください。
その後アダプタは、関連するビジネス・サービス・クラスの内部 ProcessInput() メソッドを呼び出し、スナップショット・オブジェクトを入力として渡します。
-
-
ビジネス・サービス・クラスの内部 ProcessInput() メソッドが実行されます。このメソッドは、監視およびエラー・ログの作成などの基本の Ensemble タスクを実行します。これらのタスクは、すべてのビジネス・サービスに必要です。ビジネス・サービス・クラスが継承するこのメソッドは、カスタマイズや上書きを行いません。
-
次に、ProcessInput() メソッドがカスタムの OnProcessInput() メソッドを呼び出し、スナップショット・オブジェクトを入力として渡します。このメソッドの要件については、この後の “OnProcessInput() メソッドの実装” で説明します。
以下の図は、全体的なフローを示しています。
アダプタを使用するビジネス・サービスの作成
このアダプタをプロダクションで使用するには、ここに記載されているように新しいビジネス・サービスを作成します。後で、それをプロダクションに追加して、構成します。存在しなければ、適切なメッセージ・クラスを作成する必要もあります。"Ensemble プロダクションの開発" の “Ensemble メッセージの定義” を参照してください。
ビジネス・サービス・クラスの基本要件を以下に列挙します。
-
ビジネス・サービス・クラスは Ens.BusinessServiceOpens in a new tab を拡張するものでなければなりません。
-
クラスの ADAPTER パラメータは EnsLib.SQL.InboundAdapterOpens in a new tab である必要があります。
-
クラスには OnProcessInput() メソッドを実装する必要があります。これについては、“OnProcessInput() メソッドの実装” で説明します。
-
必要に応じて、クラスで OnInit() を実装できます。“アダプタの初期化” を参照してください。
-
その他のオプションと一般情報は、"Ensemble プロダクションの開発" の “ビジネス・サービス・クラスの定義” を参照してください。
以下の例は、必要となる一般的な構造を示しています。
Class ESQL.NewService1 Extends Ens.BusinessService
{
Parameter ADAPTER = "EnsLib.SQL.InboundAdapter";
Method OnProcessInput(pInput As EnsLib.SQL.Snapshot, pOutput As %RegisteredObject) As %Status
{
Quit $$$ERROR($$$NotImplemented)
}
}
スタジオには、上記のようなスタブの作成に使用できるウィザードが用意されています。このウィザードにアクセスするには、[ファイル] メニューで [新規作成] をクリックし、[プロダクション] タブをクリックします。ビジネス・サービスの作成を選択し、関連付ける受信アダプタとして EnsLib.SQL.InboundAdapterOpens in a new tab を選択します。これにより、ウィザードではこのアダプタに必要な固有の入力引数として EnsLib.SQL.SnapshotOpens in a new tab が使用されます。
OnProcessInput() メソッドの実装
カスタム・ビジネス・サービス・クラスにおいて、OnProcessInput() メソッドは以下のシグニチャを持つ必要があります。
Method OnProcessInput(pInput As EnsLib.SQL.Snapshot,
pOutput As %RegisteredObject) As %Status
ここで、pInput は、アダプタからこのビジネス・サービスに送信するスナップショット・オブジェクトです。これは、EnsLib.SQL.SnapshotOpens in a new tab のインスタンスです。また、pOutput は、メソッド・シグニチャに必要な汎用出力引数です。
OnProcessInput() メソッドは、以下の一部またはすべてを実行する必要があります。
-
ビジネス・サービスから送信されることになる要求メッセージのインスタンスを作成します。
メッセージ・クラスの作成方法は、"Ensemble プロダクションの開発" の “Ensemble メッセージの定義” を参照してください。
-
要求メッセージに対し、スナップショット・オブジェクトの値を使用して適切にプロパティを設定します。このオブジェクトはクエリによって返される個別行に対応します。詳細は、“デフォルトのスナップショット・オブジェクトの使用法” を参照してください。
-
ビジネス・サービスの適切なメソッドを呼び出して、要求をプロダクション内の宛先に送信します。具体的には、SendRequestSync()、SendRequestAsync()、または (あまり一般的ではない) SendDeferredResponse() を呼び出します。詳細は、"Ensemble プロダクションの送信" の “要求メッセージの定義” を参照してください。
これらの各メソッドは、ステータス (具体的には、%StatusOpens in a new tab のインスタンス) を返します。
-
必要に応じて、以前のアクションのステータスを確認し、そのステータスに基づいて対応します。
-
必要に応じて、ビジネス・サービスが受信した応答メッセージを調査し、それに基づいて対応します。
-
適切なステータスを返します。
簡単な例を以下に示します。
Method OnProcessInput(pInput As EnsLib.SQL.Snapshot,
pOutput As %RegisteredObject) As %Status
{
set req=##class(ESQL.request).%New()
set req.CustomerID=pInput.Get("CustomerID")
set req.SSN=pInput.Get("SSN")
set req.Name=pInput.Get("Name")
set req.City=pInput.Get("City")
set sc=..SendRequestSync("ESQL.operation",req,.pOutput)
quit sc
}
この例では、EnsLib.SQL.SnapshotOpens in a new tab の Get() メソッドを使用して、個々の列のデータを取得します。詳細は、“デフォルトのスナップショット・オブジェクトの使用法” を参照してください。
デフォルトのスナップショット・オブジェクトの使用法
EnsLib.SQL.InboundAdapterOpens in a new tab と連携して動作するビジネス・サービス・クラスを作成すると、アダプタからカスタムの OnProcessInput() メソッドにスナップショット・オブジェクト (EnsLib.SQL.SnapshotOpens in a new tab のインスタンス) が渡されます。このインスタンスには、クエリから返されたデータのうちの 1 行分のデータが含まれています。通常、OnProcessInput() メソッドでは、このオブジェクトに含まれているデータを使用します。
EnsLib.SQL.SnapshotOpens in a new tab クラスには、複数行を管理するためのプロパティおよびメソッドが用意されています。ただし、複数行のスナップショットは、このドキュメントで後述するように、送信アダプタを使用する操作にのみ関連しています。
以下に、カスタムの OnProcessInput() メソッド内で一般に使用されるメソッドについて説明します。
method Get(pName As %String, pRow=..%CurrentRow) returns %String
現在行 (この場合の唯一の行) で名前 pName を持つ列の値を返します。
method GetColumnId(pName As %String) returns %Integer
名前 pName を持つ列の順序位置を返します。不慣れなテーブルを使用する際に、このメソッドは役に立ちます。
method GetData(pColumn As %Integer, pRow=..%CurrentRow) returns %String
現在行 (この場合の唯一の列) で、pColumn で指定されている位置にある列の値を返します。左から順に、最初の列が 1、2 番目の列が 2 などとなります。
method GetColumnName(pColumn As %Integer = 0)
pColumn で指定されている位置にある列の名前を返します。
method GetColumnSize(pColumn As %Integer = 0)
pColumn で指定されている位置にあるデータベース・フィールドのサイズ (文字数で表した幅) を返します。
method GetColumnType(pColumn As %Integer = 0)
pColumn で指定されている位置にある列の SQL タイプを返します。例えば、VARCHAR、DATE、または INTEGER などです。
SQL タイプ名は、データベースのベンダごとに異なります。
以下に、Get() メソッドを使用してスナップショットからデータを抽出し、抽出したデータを使用して要求メッセージを設定する方法を示します。
set req=##class(ESQL.request).%New()
set req.CustomerID=pInput.Get("CustomerID")
set req.SSN=pInput.Get("SSN")
set req.Name=pInput.Get("Name")
set req.City=pInput.Get("City")
アダプタの初期化
受信アダプタを初期化するには、カスタム・ビジネス・サービス・クラスの OnInit() メソッドをカスタマイズします。このメソッドはビジネス・ホストの起動時に実行されます。デフォルトでは、このメソッドは何も実行しません。
Method OnInit() As %Status
アダプタを初期化する最も一般的な理由は、クエリのパラメータとして使用する値を初期化することです。これについては、“受信クエリの指定” で説明します。以下に、関連するメソッドと例を示します。
永続値の初期化
EnsLib.SQL.InboundAdapterOpens in a new tab には、ビジネス・サービスの再起動と再起動間に保存される永続値を初期化する以下のメソッドが用意されています。
ClassMethod InitializePersistentValue
(pConfigName As %String,
pPersistentValueName As %String = "%LastKey",
pNewValue As %String)
As %String
このメソッドを使用して、アダプタに関連付けられている名前と値のペアを初期化し、その名前をクエリのパラメータに使用します。このメソッドでは、指定された永続的な名前と値のペアの現在の値を調べます。値が現時点で NULL の場合は、それを pNewValue と等しくなるように設定します。
デフォルトでは、名前を省略すると、メソッドにより、永続的な名前と値のペア &%LastKey が初期化されます。%LastKey には、アダプタによって最後に処理された行の IDKey 値が含まれています。
場合によっては、代わりに InitializeLastKeyValue() が必要な場合があります。このメソッドは、アダプタの一時プロパティ %LastKey を初期化します。このプロパティは、ビジネス・サービスが起動するたびにリセットされます。関連する SetPersistentValue() メソッドおよび GetPersistentValue() メソッドについては、EnsLib.SQL.InboundAdapterOpens in a new tab のクラスに関するドキュメントも参照してください。
例
&%LastKey 永続値を初期化するには、ビジネス・サービスの OnInit() メソッドをカスタマイズして以下を含めます。
Method OnInit() As %Status
{
#; initialize persistent last key value
Do ..Adapter.InitializePersistentValue(..%ConfigName,,0)
Quit $$$OK
}
&TopSales 永続値を初期化するには、ビジネス・サービスの OnInit() メソッドをカスタマイズして以下を含めます。
Method OnInit() As %Status
{
#; must initialize so the query can do a numeric comparison
Do ..Adapter.InitializePersistentValue(..%ConfigName,"TopSales",0)
Quit $$$OK
}
ビジネス・サービスの追加と構成
ビジネス・サービスを Ensemble プロダクションに追加するには、管理ポータルを使用して以下の操作を行います。
-
カスタム・ビジネス・サービス・クラスのインスタンスを Ensemble プロダクションに追加します。
-
ビジネス・サービスを有効化します。
-
PoolSize 設定を 1 にします。
PoolSize が 1 より大きい場合、アダプタは多数のレコードを 2 回処理します。
-
特定の外部データ・ソースと通信を行うためのアダプタを構成します。具体的には、以下を行います。
-
アダプタの接続先であるデータ・ソース名の指定
-
アダプタが実行するクエリを指定します。
-
プロダクションのその他の一般的な実行時設定の指定
これらのトピックについては、この章で後から説明します。
-
-
プロダクションを実行します。
データ・ソース名の指定
EnsLib.SQL.InboundAdapterOpens in a new tab には、接続先のデータ・ソースの指定に使用する実行時設定が用意されています。ビジネス・サービスを構成する場合は、この設定に適切な初期値を設定する必要があります。
このデータ・ソース名は、接続先である外部データ・ソースを指定します。Ensemble では、定義済みの Caché SQL ゲートウェイ接続、JDBC URL、およびオペレーティング・システムで構成した ODBC DSN の 3 種類の形式を自動的に区別します。
この名前が管理ポータルの システム, 構成, オブジェクト/SQLゲートウェイ設定 ページから構成された JDBC または ODBC 接続名に一致すると、その仕様のパラメータが Ensemble で使用されます。エントリが構成済みの接続名ではなく、そこにコロン (:) が使用されていると、その名前は JDBC URL と見なされます。それ以外の場合は ODBC DSN と見なされます。
以下の例は、JDBC URL を参照する DSN の名前を示しています。
jdbc:Cache://localhost:9982/Samples
以下の例は、Microsoft Access データベースを参照する ODBC DSN の名前を示しています。
accessplayground
このデータ・ソースがパスワードによって保護されている場合は、ユーザ名とパスワードを含む Ensemble 認証情報を作成します。その後、これらの認証情報の ID と一致するように Credentials を設定します。詳細は、“その他の実行時設定の指定” を参照してください。
JDBC データ・ソースを使用している場合は、以下の設定も適用されます。
このオペレーションで使用する Java ゲートウェイ・サーバを制御する Java ゲートウェイ・サービスの構成名です。
この設定は、JDBC と接続中の SQL ゲートウェイ接続を使用している場合でも、すべての JDBC データ・ソースで必要です。JDBC 接続が機能するには、タイプが EnsLib.JavaGateway.ServiceOpens in a new tab のビジネス・サービスが存在する必要があります。SQL アダプタに対して、この構成項目の名前を指定する必要があります。その構成済み設定を使用して、このアダプタが管理する JVM に接続します。
JDBC ドライバ・クラス名です。
名前付き SQL ゲートウェイ接続を DSN として使用する場合、この値の指定は任意です。ただし、値を指定すると、名前付き JDBC SQL ゲートウェイ接続のプロパティよりも優先して適用されます。
JDBC ドライバ・クラス名のクラスパスです (Java ゲートウェイ・サービスで構成したクラスパス以外にも必要な場合)。
必要に応じて設定できる一連の SQL 接続属性オプション。ODBC の場合は、これらの形式は次のとおりです。
attr:val,attr:val
例 : AutoCommit:1
JDBC の場合は、これらの形式は次のとおりです。
attr=val;attr=val
例 : TransactionIsolationLevel=TRANSACTION_READ_COMMITTED
名前付き JDBC SQL ゲートウェイ接続を DSN として使用する場合、この値の指定は任意です。ただし、値を指定すると、名前付き JDBC SQL ゲートウェイ接続のプロパティよりも優先して適用されます。
受信クエリの指定
デフォルトでは、EnsLib.SQL.InboundAdapterOpens in a new tab はクエリを定期的に実行します (また、結果を行ごとにビジネス・サービスに送信します)。ここでは、以下について説明します。
クエリの指定
受信 SQL アダプタで使用される基本のクエリを指定するには、Query 設定を使用します。この設定では、基本のクエリ文字列を指定します。置き換え可能なパラメータの表現には、標準の SQL ? を使用できます。これは、個別の設定で指定します (次の項目を参照)。以下の例を検討します。
SELECT * FROM Customer
SELECT p1,p2,p3 FROM Customer WHERE updatetimestamp > ?
SELECT * FROM Sample.Person WHERE ID > ?
SELECT * FROM Sample.Person WHERE Age > ?, PostalCode = ?
パラメータの指定
Parameters 設定では、クエリ文字列内の置き換え可能なパラメータを指定します。この設定は、以下のような、パラメータ値指定子のカンマ区切りリストになります。
value,value,value,...
指定する値ごとに、10 や Gotham City などの定数リテラル値を使用したり、以下のいずれかを参照したりできます。
-
アダプタのプロパティを使用できます。Parameters 設定でアダプタのプロパティを参照するには、プロパティの名前を使って参照するだけです。
-
関連するビジネス・サービスのプロパティを参照できます。構文 $property_name を使用します。
Parameters 設定でパラメータ名がドル記号 ($) で始まる場合は、その名前はサービス・クラスのプロパティであると見なされます。
例えば、タイムスタンプを入れるために、LastTS という名前のプロパティをビジネス・サービス・クラスに追加できます。Parameters 設定では、プロパティの値を $LastTS として参照します。
-
&%LastKey などの特別な永続値を参照できます。この値には、アダプタによって最後に処理された行の IDKey 値が含まれています。
Parameters 設定でパラメータ名がアンパサンド (&) で始まる場合は、その名前は特別な永続値であると見なされます。
新規行のみの処理
同じデータに対してクエリを実行し続けるのは望ましくない場合がよくあるため、EnsLib.SQL.InboundAdapterOpens in a new tab には、処理済みの行の追跡に使用できるツールがいくつか用意されています。ここでは、これらのツールおよびその実際の使用方法について説明します。
PoolSize 設定は必ず 1 に設定します。1 より大きい場合、アダプタは多数のレコードを 2 回処理します。
利用可能なツール
EnsLib.SQL.InboundAdapterOpens in a new tab には、処理済みの行を追跡するための以下のツールが用意されています。
-
KeyFieldName 設定を指定すると、アダプタがどの行を処理したかを示すデータが Caché グローバルに追加されます。この設定は、時間が経過しても再利用されない値を含むフィールドを参照します。このフィールドは、クエリから返される結果セットに含まれている必要があります。アダプタは、そのフィールドのデータを使用して、行が以前に処理されたことがあるかどうかを評価します。
-
アダプタには、永続値、&%LastKey が用意されています。この永続値には、最後に処理された行の Key Field Name の値が含まれています。この特別な永続値は、ビジネス・サービスの再起動時に保存されます。
-
アダプタの一時プロパティ %LastKey には、アダプタが最後に処理した行の KeyFieldName の値が格納されます。このアダプタ・プロパティは、関連するビジネス・サービスを再起動するたびに作成されます。
最後とその前の 2 つのオプションが実際に役立つのは、新規行ごとに単調に値が増加するフィールドを KeyFieldName が参照している場合に限られます。“アダプタの初期化” も参照してください。
行を再処理しないための実用的な方法
同じデータを再処理しないようにするための実用的な方法は、以下の 3 つです。
-
アダプタの KeyFieldName 設定を使用します。この設定を指定すると、時間が経過しても再利用されない値を含むフィールドが参照されます。このフィールドは、クエリから返される結果セットに含まれている必要があります。KeyFieldName を指定すると、アダプタはこのフィールド内のデータに基づいて、行が既に処理されているかどうかを評価します。SELECT に擬似フィールド %ID を指定し、このフィールドを KeyFieldName として指定する場合は、KeyFieldName を ID として指定する必要があり、% (パーセント記号) は省略する必要があることに注意してください。
デフォルトは ID です。
例えば、Query を以下のように指定できます。
SELECT ID,Name,Done from Sample.Person
そして、KeyFieldName を以下のように指定します。
ID
Ensemble では、ポーリング・サイクルごとに多数の行が選択されますが、選択された行のうち新規のものは少ないので、この方法は非効率的です。
-
特別な永続値 &%LastKey (またはアダプタの一時プロパティ %LastKey) を参照するクエリ・パラメータを使用するクエリを使用します。例えば、Query を以下のように指定できます。
SELECT ID,Name,Done from Sample.Person WHERE ID>?
次に、Parameters を以下のように指定できます。
&%LastKey
“アダプタの初期化” も参照してください。
-
クエリの実行後、ソース・データを削除または更新し、クエリから同じ行が返されないようにします。そのためには、DeleteQuery 設定を使用します。デフォルトでは、EnsLib.SQL.InboundAdapterOpens in a new tab は、メイン・クエリ (Query 設定) の実行後、メイン・クエリで返された行ごとに 1 回 DeleteQuery を実行します。
このクエリには、置換可能なパラメータ (疑問符) が厳密に 1 つのみ含まれている必要があります。アダプタはこのパラメータを KeyFieldName が指定する値に置換します。
このクエリでは、ソース・データを削除または更新し、アダプタのメイン・クエリによって同じ行が選択されないようにすることができます。
例えば、Query を以下のように指定できます。
SELECT ID,Name,Done from Sample.Person WHERE Done=0
そして、DeleteQuery を以下のように指定します。
UPDATE Sample.Person SET Done=1 WHERE ID=?
行の再処理
多くの場合、SQL 受信アダプタで以前に処理された行の変更点を通知する必要があります。そのための最も簡単な方法は以下のとおりです。
-
関連するテーブルに、指定された行が変更されたかどうかを記録する列を追加します。
-
更新トリガをデータ・ソースにインストールし、適宜その列を更新します。
-
アダプタが使用するクエリ内で、この列の値を使用し、指定された行を選択するかどうかを判断します。
PoolSize 設定は必ず 1 に設定します。1 より大きい場合、アダプタは多数のレコードを 2 回処理します。
クエリ設定の使用例
ここでは、上記の設定を使用する例を示します。
例 1 : KeyFieldName の使用
最も単純な例では、Customer テーブルから行を選択します。このテーブルには主キーである CustomerID フィールドがあります。これは、新しいレコードごとに自動的に増加する整数です。重要なのは新規行のみであるため、このフィールドを KeyFieldName として使用します。プロダクションでは、アダプタに以下の設定を使用します。
設定 | 値 |
---|---|
Query | SELECT * FROM Customer |
DeleteQuery | なし |
KeyFieldName | CustomerID |
Parameters | なし |
プロダクションが起動すると、アダプタが Customer テーブルのすべての行を自動的に選択して処理します。1 つの行を処理するたびに、Ensemble イベント・ログにエントリを追加します。このエントリは以下のようなテキストになります。
Processing row '216'
ここで、'216' は、処理される行の CustomerID です。
プロダクションの起動後、各ポーリング・サイクル時に、アダプタはすべての行を選択しますが、CustomerID フィールドに新しい値が含まれている行のみを処理します。
例 2 : &%LastKey または %LastKey の使用
この例は、上記のバリエーションです。この場合は、メイン・クエリが行のサブセットを選択します。すべての行を選択するよりも効率的です。
設定 | 値 |
---|---|
Query | SELECT * FROM Customer WHERE ID>? |
DeleteQuery | なし |
KeyFieldName | CustomerID |
Parameters | &%LastKey |
各ポーリング・サイクル時に、アダプタは &%LastKey の値を決定し、その値を SQL に渡します。
“アダプタの初期化” も参照してください。
一連の行をアダプタが選択するときには、KeyFieldName で指定された順序で各行が処理されることもあれば、されないこともあります。例えば、あるポーリング・サイクルで、CustomerID が 101、102、103、104、および 105 の行を選択するとします。ただし、顧客 103 を (顧客 105 の代わりに) 最後に処理するとします。このポーリング・サイクル終了後の &%LastKey の値は 103 です。したがって、次のサイクルでは、アダプタは再処理はしないものの、顧客 104 および 105 を再度選択します(この方が、上記例のようにすべての行を再度選択するよりも効率的です)。強制的にアダプタが特定の順序で行を処理するようにするには、以下のように、クエリ内に ORDER BY 節を追加します。
SELECT * FROM Customer WHERE ID>? ORDER BY CustomerID
この場合、&%LastKey の値は常に最大の CustomerID に設定されるので、複数回選択される行はなくなります。
例 3 : DeleteQuery の使用
この例では、Customer テーブルに Done というフィールドがあります。このフィールドには、アダプタが所定の行を以前に選択したことがあるかどうかを記録できます。
設定 | 値 |
---|---|
Query | SELECT * FROM Customer WHERE Done=0 |
DeleteQuery | UPDATE Customer SET Done=1 WHERE CustomerID=? |
KeyFieldName | CustomerID |
Parameters | なし |
上記の例と同様、この例では、各行が選択されるのは 1 度だけです。
削除クエリは各行が処理されるたびに 1 回実行されるので、このクエリを使用すると処理が遅くなる可能性があります。定期的な間隔でバッチ削除 (バッチ更新) を実行するとより効率的です。
例 4 : 複合キーの使用
テーブルの複数のフィールドを主キーとしてまとめて処理する必要がある場合が多々あります。例えば、Month フィールドや Year フィールドを含む統計テーブルがあるとします。クエリでは、アダプタの一意のキーとして月と年を一緒に処理する必要があるとします。このような場合は、関連するフィールドを連結し、AS 節を使用して複合フィールドの別名を提供するクエリを使用します。
例えば、SQL*Server の場合、以下のように始まるクエリを使用できます。
SELECT Stats, Year||Month as ID ...
アダプタ内の結果セットに ID というフィールドが含まれるようになります。このフィールドを KeyFieldName に使用できます。
連結の構文は、作業しているデータベースによって異なります。
例 5 : KeyFieldName の指定なし
場合によっては、KeyFieldName を使用したくないこともあります。KeyFieldName が NULL の場合、アダプタは行を区別せず、エラーがある行や既に正常に処理された行をスキップしません。
以下に例を示します。
設定 | 値 |
---|---|
Query | Select * from Cinema.Film Where TicketsSold>? |
DeleteQuery | なし |
KeyFieldName | なし |
Parameters | &TopSales (これは、ビジネス・サービスの OnProcessInput() メソッド内で定義される、TopSales という特殊な永続値を参照します) |
ビジネス・サービスは以下のとおりです。
Class Test.SQL.TopSalesService Extends Ens.BusinessService
{
Parameter ADAPTER = "EnsLib.SQL.InboundAdapter";
Parameter REQUESTCLASSES As %String = "EnsLib.SQL.Snapshot";
Method OnInit() As %Status
{
#; must initialize so the query can do a numeric comparison
Do ..Adapter.InitializePersistentValue(..%ConfigName,"TopSales",0)
Quit $$$OK
}
Method OnProcessInput(pInput As EnsLib.SQL.Snapshot,
Output pOutput As Ens.Response) As %Status
{
Kill pOutput Set pOutput=$$$NULLOREF
for j=1:1:pInput.ColCount {
}
for i=1:1:pInput.RowCount {
for j=1:1:pInput.ColCount {
}
}
Set tSales=pInput.Get("TicketsSold")
Set:tSales>$G($$$EnsStaticAppData(
..%ConfigName,"adapter.sqlparam","TopSales")) ^("TopSales")=tSales
Quit $$$OK
}
}
その他の実行時設定の指定
EnsLib.SQL.InboundAdapterOpens in a new tab には、以下のその他の実行時設定が用意されています。
アダプタのポーリング間隔を秒単位で指定します。これは、このアダプタが入力をチェックする頻度を指定します。
ポーリング時にアダプタが入力を検出した場合は、適切な Ensemble オブジェクトを作成し、関連するビジネス・サービスにそのオブジェクトを渡します。一度に複数の入力が検出された場合は、検出されなくなるまで、アダプタが入力を順に処理します。アダプタは、検出した入力の項目ごとに 1 つの要求をビジネスサービスに送信します。その後、アダプタはポーリング間隔が経過するのを待ってから、再び入力をチェックします。プロダクションが実行中であり、ビジネス・サービスが有効化され、アクティブになるようにスケジュールされている場合、このサイクルは常に継続されます。
各入力の処理の間の CallInterval 期間をアダプタで延期できるようにビジネス・サービスのプロパティを設定することが可能です。詳細は、"Ensemble プロダクションの開発" を参照してください。
CallInterval のデフォルト値は 5 秒です。最小値は 0.1 秒です。
指定された DSN への接続を承認できる Ensemble 資格情報の ID を識別します。Ensemble 認証情報の作成方法は、"Ensemble プロダクションの構成" を参照してください。
SQL 文の送信や ODBC ドライバ設定の変更などのコマンドを実行している間、接続を開いたままにするかどうかを指定します。
-
この設定が 0 の場合は、SQL コマンドを 1 つ実行終了するたびにアダプタの接続が直ちに切断されます。
-
この設定が -1 の場合、アダプタは起動時に自動接続し、接続したままになります。この値は、例えば、データベース・トランザクションを管理している場合などに使用します。これについては、このドキュメントの “トランザクションの管理” で説明します。
この設定には正の値も使用できますが、その場合の値は SQL コマンド実行後のアイドル時間 (秒) になるので、ポーリングによって機能する SQL 受信アダプタでは役に立ちません(アイドル時間がポーリング間隔 [CallInterval] よりも長い場合、アダプタは常に接続された状態のままです。アイドル時間がポーリング間隔よりも短い場合は、ポーリング間隔ごとにアダプタの切断と再接続が発生します。つまり、アイドル時間には実質的に意味がなくなります)。
ここに記載されていない設定については、"Ensemble プロダクションの構成" を参照してください。
受信アダプタで以前に処理された行のリセット
開発およびテスト中に、以前実施したテストを繰り返すために、ビジネス・サービスのアダプタをリセットすることが役に立つ場合があります。そのためには、ここで説明する以下のメソッドのいずれかを使用します。これらは、EnsLib.SQL.InboundAdapterOpens in a new tab で継承されるクラス・メソッドです。
動作中のプロダクションでは、通常、これらのメソッドは使用しません。
ClassMethod ClearRuntimeAppData(pConfigName As %String)
指定された構成名を持つビジネス・サービスの実行時データをすべて消去します。アダプタの %ConfigName プロパティを使用すると、現在構成されているビジネス・サービスの名前にアクセスできます。このデータは、ビジネス・サービスが起動するたびに自動的に消去されます。
ClassMethod ClearStaticAppData(pConfigName As %String)
構成名で指定されているビジネス・サービスの静的データを消去します。このデータには、永続的な最後のキー値など、アダプタに関連付けられている永続値すべてが含まれています。
ClassMethod ClearAllAppData(pConfigName As %String)
このメソッドは ClearRuntimeAppData() および ClearStaticAppData() クラスのメソッドを実行します。