ストアドプロシージャの開発

Virtual DataPort は Java でカスタムのストアドプロシージャを開発するための API を備えています。

ストアドプロシージャを開発した後は、そのプロシージャを Virtual DataPort サーバーにインポートする必要があります。この方法については、管理ガイドの「 ストアドプロシージャのインポート 」を参照してください。

Denodo Platform には、ストアドプロシージャのサンプルとそのソースコードがいくつか付属します。これらは <DENODO_HOME>/samples/vdp/storedProcedures にあります。このパス内の README ファイルでは、これらのサンプルのコンパイルおよびインストールの手順について説明しています。

ストアドプロシージャを開発して Virtual DataPort にインポートした後は、Denodo ナレッジベースの記事「 How to debug Denodo custom extensions with Eclipse 」を読んでデバッグ方法について確認してください。


ストアドプロシージャを開発するためのクラスとインターフェイスは、パッケージ com.denodo.vdb.engine.storedprocedure にあります。

ここでは、このパッケージのメインクラスの使用方法について簡単に説明します。各メインクラスとそのクラスのメソッドの詳細については、 Javadoc のドキュメント を参照してください。

ストアドプロシージャを作成するには、 com.denodo.vdb.engine.storedprocedure.AbstractStoredProcedure を拡張する新しい Java クラスを作成します。

注釈

ストアドプロシージャが呼び出されるたびに、実行エンジンはこのクラスのインスタンスを作成します。そのため、このクラスは、プロシージャの実行中にその状態を格納する属性を持つことができます。たとえば、クエリで結果セットを処理する場合、処理された行の数などを持つことができます。

以下のメソッドをオーバーライドする必要があります。

  • public String getName()

    このメソッドは、ストアドプロシージャの名前を返す必要があります。

    NULL を返すことはできません。

  • public String getDescription()

    このメソッドは、ストアドプロシージャの説明を返す必要があります。

    NULL を返すことはできません。

  • public StoredProcedureParameter[] getParameters()

    このメソッドは、プロシージャが呼び出されるたびに 1 回呼び出されます。

    このメソッドは、ストアドプロシージャの入力パラメーターと出力パラメーターの配列を返す必要があります。各パラメーターは StoredProcedureParameter オブジェクトで表されます。1 つの StoredProcedureParameter オブジェクトで、1 つのパラメーターの名前、型、方向 (入力、出力、またはこの両方)、および「NULL 可能性」 (NULL 値を受け入れるかどうか) を指定します。

    パラメーターが複合型の場合は、そのフィールドについて説明する StoredProcedureParameter オブジェクトの配列を指定する必要があります。

    このメソッドは NULL を返すことはできません。入力パラメーターも出力パラメーターも持たない場合は、空の配列を返す必要があります。

    : 「 Definition of the parameters of a stored procedure with compound fields 」には、以下のパラメーターを持つストアドプロシージャの getParameters() メソッドが含まれています。

    • text 型の入力パラメーター。

    • レジスターの配列である出力パラメーター。これらのレジスターは、 field1 (text) と field2 (int) の 2 つのフィールドを持っています。

複合型フィールドを持つストアドプロシージャのパラメーターの定義
public StoredProcedureParameter[] getParameters() {

    return new StoredProcedureParameter[] {
            new StoredProcedureParameter("parameter1", Types.VARCHAR, StoredProcedureParameter.DIRECTION_IN),
            new StoredProcedureParameter("compound_field", Types.ARRAY, StoredProcedureParameter.DIRECTION_OUT,
                    true,
                    new StoredProcedureParameter[] {
                            new StoredProcedureParameter("field1", Types.VARCHAR,
                                    StoredProcedureParameter.DIRECTION_OUT),
                            new StoredProcedureParameter("field2", Types.INTEGER,
                                    StoredProcedureParameter.DIRECTION_OUT) }) };
}
  • public void doCall(Object[] inputValues)

    このプロシージャが呼び出されると、実行エンジンはこのメソッドを呼び出します。

    プロシージャが結果を返す必要がある場合は、スーパークラスの getProcedureResultSet():StoredProcedureResultSet メソッドを呼び出して、このプロシージャが返す行のリストの参照を取得する必要があります。その後、返す行ごとに、 StoredProcedureResultSetaddRow(...) メソッドを呼び出します。

    : プロシージャが、「 Definition of the parameters of a stored procedure with compound fields 」で定義されているもののような compound_field という名前の単一の出力フィールドを持っているとします。この場合、次のコードスニペットは、個々の行を構築して結果セットに追加します。

ストアドプロシージャ: 複合型の行の構築
@Override
protected void doCall(Object[] inputValues) throws
            SynchronizeException, StoredProcedureException {
    ...
    ...
    ...
    Object[] row = new Object[1];
    List<Struct> compoundField = new ArrayList<Struct>(values.size());
    List<String> fieldsNames = Arrays.asList("field1", "field2");
    /*
     * 'values' was generated before
     */
    for (Map.Entry<String, Integer> value : values.entrySet()) {

        List structValues = Arrays.asList(value.getKey()
                                          , value.getValue());
        Struct struct = super.createStruct(fieldsNames, structValues);
        compoundField.add(struct);
    }

    row[0] = createArray(compoundField, Types.STRUCT);
    getProcedureResultSet().addRow(row);
}

必要に応じて、以下のメソッドをオーバーライドすることもできます。

  • public void initialize(DatabaseEnvironment environment)

    クエリによってこのストアドプロシージャが実行されるたびに、実行エンジンはこのメソッドを 1 回呼び出します。このメソッドを、初期化タスクを実行するようにオーバーライドすることができます。

    DatabaseEnvironment クラスは、プロシージャの実行に役立つ以下のメソッドを備えています。

    • executeQuery メソッドおよび executeUpdate メソッドを使用して、クエリを実行します。

      これらのメソッドの一部のシグネチャは Object[] parameterValues パラメーターを持ちます。これらのメソッドでは、VQL ステートメント内のパラメーターをプレースホルダー ? で示し、その後、その値を配列で渡すことができます。

      ストアドプロシージャから実行されたすべてのクエリをキャンセルするには、以下を実行します。

      ((DatabaseEnvironmentImpl) this.environment).cancelQueries()

    • executeVqlCommand メソッドを使用して VQL コマンドを実行します。

      このメソッドの一部のシグネチャは、コマンドが実行されるデータベースを示す String databaseName パラメーターを持ちます。

      本番サーバーのメタデータを変更するコマンドは実行しないことを強くお勧めします。

    • 他のストアドプロシージャへの参照を取得するには、 lookupProcedure(...) を呼び出します。

    • 関数の参照を取得するには、 lookupFunction(...) を呼び出します。

    • 新しいトランザクションを作成するには、 createTransaction(...) を呼び出します。

    • 現在のトランザクションにストアドプロシージャを追加するには、 joinTransaction(...) を呼び出します。

    • サーバーのログにメッセージを書き込むには、 log(...) を呼び出します。

    • サーバーのプロパティの値を取得するには、 getDatabaseProperty(...) を呼び出します。リクエストできるプロパティは、 CURRENT_USER (現在のユーザーのユーザー名) と CURRENT_DATABASE (現在のデータベース) です。

    super.getEnvironment() を呼び出すことによって、 DatabaseEnvironment への参照を他のメソッドから取得できます。

  • public boolean stop()

    このストアドプロシージャに関連するクエリがキャンセルされると、実行エンジンはこのメソッドを呼び出します。 AbstractStoredProcedure クラスが備えているこのメソッドのデフォルトの実装は、何も行わず、単に false を返します。

    このプロシージャが実行するタスクがキャンセル可能なものであれば、このメソッドをオーバーライドして、タスクをキャンセルしてください。このプロシージャが他のシステムへのコネクションを開いたり、ファイルを開いたりする場合は、このメソッドからそれらのリソースを閉じます。

    このメソッドが true を返したら、プロシージャは、このメソッドの呼び出し後に確実に完了する必要があります。メソッドがこのプロシージャの呼び出し後に完了しない場合は、 false を返すようにします。

    このプロシージャでこのメソッドを上書きしない場合、実行エンジンはこのプロシージャの実行を中断しようとします。そのため、このメソッドの上書きは、推奨されますが必須ではありません。

  • public void prepare()

    実行エンジンは、このプロシージャに関連するトランザクションを開始しようとするときに、このメソッドを呼び出します。

  • public void commit()

    実行エンジンは、現在のトランザクションを確定する場合にこのメソッドを呼び出します。

  • public void rollback()

    実行エンジンは、現在のトランザクションを元に戻す場合にこのメソッドを呼び出します。

  • public boolean caseSensitiveParameters()

    ストアドプロシージャで定義している入力パラメーターと出力パラメーターの名前で大文字と小文字が区別される場合は、このメソッドをオーバーライドして true を返すようにします。

  • public void log(level, message)

    Virtual DataPort のログシステムにメッセージを記録します。メッセージは、このプロシージャのクラスの名前が付いたログカテゴリに追加されます。つまり、プロシージャのクラスが com.acme.procedure1 である場合、メッセージはカテゴリ com.acme.procedure1 に追加されます。

    このログカテゴリが有効化されていると、メッセージは <DENODO_HOME>/logs/vdp/vdp.log に記録されます。

    ログカテゴリを有効化するには、 <DENODO_HOME>/conf/vdp/log4j.xml を変更するか、または LOGCONTROLLER ストアドプロシージャを呼び出します。詳細については、管理ガイドの「 ログエンジンの構成 」を参照してください。


AbstractStoredProcedure には、この他にも以下の有用なメソッドがあります。

  • static java.sql.Struct createStruct(Collection values, int type): このメソッドは、SQL 型オブジェクト struct を作成します。エレメントのレジスターを作成するには、このメソッドを呼び出します。「 Stored procedures: building a row of a compound type 」の例を参照してください。

  • static java.sql.Array createArray(Collection values, int type): このメソッドは配列を返します。エレメントの配列を作成するには、このメソッドを呼び出します。リスト内のエレメントは java.sql.Struct 型でなければなりません。この型のエレメントは createStruct(...) を呼び出すことによって作成できます。「 Stored procedures: building a row of a compound type 」の例を参照してください。