NoSQLデータへのSQLアクセス:返されたメタデータを動的に定義するCachéでのSQLプロシージャの実装

ご存じのように、Cachéは、任意のSQLクエリを実行し、SQLプロシージャを呼び出す機能を備えた、 JDBC / ODBCドライバを含むリレーショナルDBMSとして使用できます。
また、Cachéのすべてのデータは、多次元のスパース配列( グローバル)に格納されることも知られています 。 これにより、個々のSQLプロシージャのパフォーマンスが不十分な場合、標準のCachéSQLエンジンを使用するのではなく、CachéObjectScript(COS)サーバーのビジネスロジック言語で実行コードを書き換えることができます。 NoSQLデータ構造(グローバル)。
ただし、Caché標準クラスライブラリには、1つの制限があります。COSコードを使用して選択が実行されるSQLプロシージャの場合、コンパイル段階で返されるフィールドのセットを決定する必要があります。 NoSQL構造で動作するSQLプロシージャのメタデータを動的に設定する方法はありません。

この制限を削除する方法は、カットの下で説明されています。

CachéでのSQLプロシージャの使用

JDBC / ODBCを介した非リレーショナルCaché構造へのクエリは、以下のストアドプロシージャを使用して実装されます。

画像

このようなストアドプロシージャは、1つ以上のレコードセット(ResultSets)、またはスカラー値を返すことができます。

例として、ODBCを操作するツールの1つを使用して、サンプル領域からストアドプロシージャsample.SP_Sample_By_Nameを呼び出します。

画像

SQLプロシージャのシグネチャでは、何が返されるかはわかりませんが、これはプロシージャの実行中にのみ認識されます。

Cachéでは、値を返すかResultSetを返すクラスメソッドをSQLプロシージャに格納できます。 たとえば、ResultSetを返すストアドプロシージャが宣言されています。

ClassMethod SomeSqlProc( p1 As%Integer = 0 )[ ReturnResultsets SqlProc ]

この構造を使用して、ResultSet(またはそれ以上)を返すストアドプロシージャとしてODBC経由で呼び出すことができるCachéObjectScriptコードを記述できます。

Cachéには、ResultSetの形式で返されるNoSQLデータを生成するための2つの標準メソッドがあります。

最初の方法。 クラスクエリの使用

クラスクエリの使用
ClassMethod SomeSqlProc( p1 As%Integer = 0 )[ ReturnResultsets SqlProc ]
{
if ' $ isobject $ Get %sqlcontext )) { set sqlcontext = ## class %ProcedureContext )。 %新規 () }
クエリ = ##クラス %ResultSet )を 設定し ます %新規 "User.SomeClass:Query"
クエリを実行 ます 実行 p1
%sqlcontextを実行し ます。 AddResultSet query
}

詳細はこちら

このメソッドを使用すると、CachéObjectScriptでデータを生成するための任意のコードを作成できますが、返されるResultSetのメタデータは、%Queryに基づいてコンパイラによって作成されます。#ROWSPECパラメータ、つまり コンパイル時に。

2番目の方法。 %SQL.CustomResultSetを使用する

%SQL.CustomResultSetを使用する
ClassMethod SomeSqlProc( p1 As%Integer = 0 )[ ReturnResultsets SqlProc ]
{
if ' $ isobject $ Get %sqlcontext )) { set sqlcontext = ## class %ProcedureContext )。 %新規 () }
クエリ = ##クラス User.MyResultSet )を 設定し ます %新規 (、 p1
%sqlcontextを実行し ます。 AddResultSet query
}

実装ある %SQL.CustomResultSetの詳細をご覧ください。

このメソッドは前のメソッドと似ていますが、メタデータは、継承クラス%SQL.CustomResultSetの定義に基づいて生成されます-前の場合と同様に、コンパイル時に。

注:同じ方法でSQLデータを取得できます。

SQLデータの取得
ClassMethod SomeSqlProc( p1 As%Integer = 0 )[ ReturnResultsets SqlProc ]
{
s sqltext = "SELECT * FROM dbo.Classname" ##; リクエストテキストを準備します
if ' $ isobject $ Get %sqlcontext )) { set sqlcontext = ## class %ProcedureContext )。 %新規 () }
クエリ = ##クラス %ResultSet )を 設定し ます %新規 "%DynamicQuery:SQL"
クエリを実行 ます 準備 sqltext
クエリを実行 ます 実行 ()
%sqlcontextを実行し ます。 AddResultSet query
}

この場合、メタデータは実行時に生成されますが、データはSQLからのみ取得できます。

したがって、実行時に結果メタデータを生成し、任意のCachéObjectScriptを使用してデータを生成する場合、Cachéが提供する資金が十分でないことは明らかです。

問題解決

この問題には4つの解決策があります。


私は最後の方法を選びました-それは私には最もエレガントであるように見えました(先を見て、私はまだ松葉杖なしではできませんでした)。

最初に、User.Queryクラスを作成し、%Queryから継承します-all%Queryの実装を上書きしないようにします。 %Queryを使用する場合、コンシューマー(%ResultSet)は、GetInfoおよびGetODBCInfoの2つのクラスメソッドを介してメタデータを要求します。 後継クラスでは、これらのメソッドの代替実装を作成する必要があります。 いくつかの実験を通して(これはジェネレーターを理解するよりも簡単です)GetInfoパラメーター(.colinfo、.parminfo、.idinfo、.qHandle、extoption、.extinfo)について知りました:



GetODBCInfoを使用すると、すべてが類似しており、もう少しフィールドがあり、結果を単一レベルのリストに追加する必要がありますが、一般的には同じです。

GetInfoおよびGetODBCInfoから正しいメタデータを返すために、あまり明確ではないいくつかのトリックを見つける必要があります。これらのトリックは主に以下のとおりです。

Source: https://habr.com/ru/post/J160147/


All Articles