リレーションシップ・データベースの照会の実行

関係を使用する場合、関係定義についての情報を取得する必要がある場合があります。関係情報はリレーションシップ・データベースの特別な表に格納されます。関係についての情報を取得するには、その関係表を照会します。照会 は、データベースに送信して実行させる、通常は SQL (Structured Query Language) ステートメント形式の要求です。

リレーションシップ・データベースに照会を実行するには、次の手順を行います。

  1. リレーションシップ・データベースへの接続を開いて、DtpConnection オブジェクトを取得します。
  2. DtpConnection オブジェクトを使用して、照会を実行し、リレーションシップ・データベース内のトランザクションを管理します。

マップの実行が完了すると、接続は自動的にクローズします。

要確認:
DtpConnection クラスとそのメソッドを使用してリレーションシップ・データベースへの接続を確立することは、後方互換性のためのみ にサポートされています。これらの使用すべきでないメソッド によりエラーが生成されることはありませんが、これらのメソッドを使用せずに、既存のコードを新しいメソッドに移行することを推奨します。

使用すべきでないメソッドは、今後のリリースで除外されることがあります。新規マップの開発では、CwDBStoredProcedureParam クラスとそのメソッドを使用して、データベース接続を取得し、SQL 照会を実行します。詳細については、"データベース照会の実行"を参照してください。

接続のオープン

リレーションシップ・データベースの照会を行うには、最初に BaseDLM クラスのgetRelConnection() メソッドを使用してこのデータベースへの接続をオープンする必要があります。

オープンするリレーションシップ・データベースを識別するには、照会を行う関係定義の名前を指定します。リポジトリーで各関係定義の関係表のロケーションを追跡します。 詳細については、"関係定義の拡張設定"を参照してください。

例: 次の getRelConnection() 呼び出しにより SapCust 関係の関係表を含むリレーションシップ・データベースがオープンします。

DtpConnection connection = getRelConnection("SapCust");
 

この呼び出しにより connection 変数に DtpConnection オブジェクトが戻され、その後この変数を使用してリレーションシップ・データベースにアクセスできます。

照会の実行

executeSQL() メソッドにより、実際の照会がリレーションシップ・データベースに送信されて実行されます。 このセクションでは、以下の種類の SQL 照会の実行について説明します。

データを戻す照会 (SELECT)

SQL ステートメント SELECT は、1 つ以上の表のデータを照会します。SELECT ステートメントをリレーションシップ・データベースに送信して実行させるには、SELECT のストリング表記を引き数として executeSQL() メソッドに指定します。

注:
DtpConnection.executeSQL() メソッドは、後方互換性のためにのみサポートされています。新規コードの開発ではこのメソッドを使用しないでください。代わりに、CwDBConnection クラスの executeSQL() メソッドを使用してください。

例: executeSQL() への次の呼び出しにより、RelRT_T 表からの 1 つの列値を取得する SELECT が送信されます。

connection.executeSQL(
    "select data from RelRT_T where INSTANCEID = 2");
 

注:
前述のコードでは、connection 変数は前の getRelConnection() メソッドの呼び出しで取得した DtpConnection オブジェクトです。

また、executeSQL() メソッドの 2 番目の形式を使用して、パラメーターを持つ SELECT ステートメントを送信することもできます。

例: 次のexecuteSQL() への呼び出しにより、前述の例と同じ操作が行われます。ただし、この場合、インスタンス ID がパラメーターとして SELECT ステートメントに渡されます。

Vector argValues = new Vector();
  
 String instance_id = "2";
 argValues.addElement( instance_id );
 connection.executeSQL(
    "select data from RelRT_T where INSTANCEID = ?", argValues);
 

SELECT ステートメントでは、関係表からデータが行として戻されます。各行は、SELECT の条件と一致する指定された関係表の 1 行です。各行には、SELECT ステートメントが指定した列の値が含まれます。戻されたデータは、これらの行および列による 2 次元配列として表示できます。

ヒント:
SELECT ステートメントの構文は、アクセスする特定のリレーションシップ・データベースに対して有効である必要があります。SELECT ステートメントの正確な構文については、データベース文書を確認してください。

戻されたデータにアクセスするには、次の手順を実行します。

  1. 1 行のデータを取得します。
  2. 列の値を 1 つずつ取得します。

表 115 に、戻された照会データにアクセスするための DtpConnection クラスのメソッドを示します。

表 115.
行にアクセスするための DtpConnection メソッド
行にアクセスするための操作 DtpConnection メソッド
行があるかどうかのチェック hasMoreRows()
1 行のデータの取得 nextRow()

hasMoreRows() メソッドを使用して、戻された行のループを制御します。hasMoreRows() から false が戻されると、行ループが終了します。1 行のデータを取得するには、nextRow() メソッドを使用します。このメソッドは、選択された列の値を Java Vector オブジェクトの要素として戻します。 これにより、Enumeration クラスを使用して、列の値に個別にアクセスできます。 VectorEnumeration の両クラスは java.util パッケージに存在します。 戻された照会行の列にアクセスするための Java メソッドについては、表 71 を参照してください。

注:
照会結果の行にアクセスするメカニズムは、使用すべきでない DtpConnection クラスと、その置き換えである CwDBConnection クラスでは同じです。詳細については、"データを戻す静的照会の実行 (SELECT)"を参照してください。

例: 以下のコード例では、sampleRelationshipName 関係定義を保管するリレーションシップ・データベースへ接続する DtpConnection クラスのインスタンスを取得します。次に、SELECT ステートメントが実行され、「CrossWorlds」の単一ストリング値が含まれる 1 行のみが戻されます。

Vector theRow = null;
 Enumeration theRowEnum = null;
 String theColumn1 = null;
 DtpConnection connectn = null;
  
 try
    {
    connectn = getRelConnection("sampleRelationshipName");
    }
  
 catch(DtpConnectionException e)
    {
    System.out.println(e.getMessage());
    }
  
 // Test for a resulting single column, single row, result set
 // specified condition
 try
    {
    connectn.executeSQL(
       "select data from RelRT_T where INSTANCEID = 2");
  
    // Loop through each row
    while(connectn.hasMoreRows())
       {
       theRow = connectn.nextRow();
       int length = 0;
       if ((length = theRow.size())!= 1)
          {
          return "Expected result set size = 1," +
             " Actual result state size = " + length;
          }
  
       // Get each column
       theRowEnum = theRow.elements();
       if(theRowEnum.hasMoreElements())
          {
          // Get the value
          theColumn1 = (String)theRowEnum.nextElement();
          if(theColumn1.equals("CrossWorlds")==false)
             {
             return "Expected result = CrossWorlds,"
                + " Resulting result = " + theColumn1;
             }
          }
       }
    }
  
 catch(DtpConnectionException e)
    {
    System.out.println(e.getMessage());
    }
 

注:
SELECT ステートメントでは、リレーションシップ・データベースの内容は変更されません。したがって、通常は SELECT ステートメントのトランザクション管理を行う必要はありません

関係表を変更する照会

関係表のデータを変更する SQL ステートメントには、以下が含まれます。

これらのステートメントのリレーションシップ・データベースに送信して実行させるには、executeSQL() メソッドの引き数として、ステートメントをストリング表記で指定します。

注:
DtpConnection.executeSQL() メソッドは、後方互換性のためにのみサポートされています。新規コードの開発ではこのメソッドを使用しないでください。代わりに、CwDBConnection クラスの executeSQL() メソッドを使用してください。

例: 次のexecuteSQL() への呼び出しにより、RelRT_T 表への 1 行の INSERT が送信されます。

connection.executeSQL("insert into RelRT_T values 
 (1, 3, 6)");
 

注:
前述のコードでは、connection 変数は前の getRelConnection() メソッドの呼び出しで取得した DtpConnection オブジェクトです。

UPDATE または INSERT ステートメントの場合、getUpdateCount() メソッドを使用して、変更または追加された関係表の行数を判別できます。

INSERT、UPDATE、および DELETE ステートメントはリレーションシップ・データベースの内容を変更するため、これらのステートメントについては、トランザクション管理を行う必要がありますトランザクション は、1 単位として実行される操作ステップの集合です。 トランザクション内で実行されるすべての SQL ステートメントは、1 単位として成功または失敗します。表 116 に、SQL 照会のトランザクション・サポートを行う DtpConnection クラスのメソッドを示します。

表 116.
トランザクション管理のための DtpConnection メソッド
トランザクション管理操作 DtpConnection メソッド
新しいトランザクションを開始します。 beginTran()
トランザクションの実行時にデータベースに対して行われたすべての変更をコミット (保管) し、トランザクションを終了します。 commit()
トランザクションが現在アクティブかどうかを確認します。 inTransaction()
トランザクションの実行時に行われたすべての変更をロールバック (バックアウト) し、トランザクションを終了します。 rollBack()

リレーションシップ・データベース内のトランザクションの開始をマーク付けするには、beginTran() メソッドを使用します。この beginTran() 呼び出しとトランザクションの終了の間で、単位として成功または失敗となるすべての SQL ステートメントを実行します。以下のいずれの方法でも、トランザクションを終了できます。

トランザクションが失敗した原因となる条件を選択できます。失敗条件が満たされた場合は、条件をテストし、rollBack() を呼び出します。あるいは、commit() を呼び出して、トランザクションを正常終了します。

DtpConnection connection = getRelConnection("SapCust");
  
 // begin a transaction
 connection.beginTran();
  
 // insert a row
 connection.executeSQL("insert...");
  
 // commit the transaction
 connection.commit();
  
 // release the database connection
 releaseRelConnection(true);
 

トランザクションが現在アクティブであるかどうかを判別するには、inTransaction() メソッドを使用します。

ストアード・プロシージャーを呼び出す照会

ストアード・プロシージャーは、SQL ステートメントおよび条件ロジックが含まれるユーザー定義のプロシージャーです。ストアード・プロシージャーは、データベースに格納されます。新しい関係を作成する場合、各関係表を保守するためにストアード・プロシージャーが作成されます。

表 117 に、ストアード・プロシージャーを呼び出す DtpConnection クラスのメソッドを示します。これらのメソッドは、後方互換性のためにのみサポートされています。新規コードの開発ではこのメソッドを使用しないでください。代わりに、CwDBConnection クラスの executeSQL()executeStoredProcedure() メソッドを使用してください。

表 117.
ストアード・プロシージャーを呼び出す DtpConnection メソッド
ストアード・プロシージャーの呼び出し方法 DtpConnection メソッド 使用
ストアード・プロシージャーを実行する CALL ステートメントをリレーションシップ・データベースに送信します。 executeSQL() OUT パラメーターを持たない ストアード・プロシージャーを呼び出します。
ストアード・プロシージャーの名前およびそのパラメーターの配列を指定してプロシージャー呼び出しを作成します。これがリレーションシップ・データベースに送信されて実行されます。 execStoredProcedure() OUT パラメーターがある任意のストアード・プロシージャーを呼び出すため。

注:
JDBC メソッドを使用して、ストアード・プロシージャーを直接実行できます。しかし、マッピング API に用意されている単純なインターフェースを使用して、データベース・リソースを再使用し、実行効率を向上することができます。ストアード・プロシージャーはマッピング API を使用して実行する必要があります。

表 117 に示す、どのメソッドを使用してストアード・プロシージャーを呼び出すかは、以下によって決まります。

次のセクションでは、executeSQL()execStoredProcedure() メソッドを使用した、ストアード・プロシージャーの呼び出し方法を説明します。

executeSQL() によるストアード・プロシージャーの呼び出し

executeSQL() メソッドを使用してストアード・プロシージャーを呼び出すには、executeSQL() メソッドの引き数として、ストアード・プロシージャーとすべて引き数を含ませた CALL ステートメントをストリング表記で指定します。

例: 次の executeSQL() 呼び出しにより、setOrderCurrDate() ストアード・プロシージャーを実行する CALL ステートメントが送信されます。

connection.executeSQL("call setOrderCurrDate(345698)");
 

注:
前述のコードでは、connection 変数は前の getRelConnection() メソッドの呼び出しで取得した DtpConnection オブジェクトです。

setOrderCurrDate() ストアード・プロシージャーを実行できます。その単一引き数が IN パラメーターである、つまり、その値がストアード・プロシージャーにのみに送信されるためです。このストアード・プロシージャーは、どの OUT パラメーターも使用しません。

注:
パラメーター配列を受け入れる executeSQL() の形式を使用して、パラメーター値を渡すことができます。ただし、executeSQL() を使用して OUT パラメーターを使用するストアード・プロシージャーを呼び出すことはできません。このようなストアード・プロシージャーを実行するには、execStoredProcedure() を使用する必要があります

DtpConnection executeSQL メソッドを使用して、ODBC を介して Oracle ストアード PL/SQL オブジェクトを呼び出す場合は、匿名 PL/SQL ブロックを使用します。以下は、受け入れ可能なフォーマットを示します (ストアード・プロシージャー名は myproc です)。

executeSQL("begin myproc(...); end;");
 

execStoredProcedure() によるストアード・プロシージャーの呼び出し

execStoredProcedure() メソッドを使用してストアード・プロシージャーを呼び出す手順は、以下のとおりです。

  1. 実行するストアード・プロシージャーの名前をストリングで指定します。
  2. UserStoredProcedureParam オブジェクトの Vector パラメーター配列を作成します。これによりパラメーター情報 (各パラメーターの名前、タイプ、および値など) が指定されます。

パラメーターは、ストアード・プロシージャーに対して、またはストアード・プロシージャーから送信できる値です。パラメーターのイン/アウト・タイプにより、ストアード・プロシージャーがパラメーター値を使用する方法が決まります。

UserStoredProcedureParam オブジェクトは、ストアード・プロシージャーの単一のパラメーターについて記述します。表 118 に、UserStoredProcedureParam オブジェクトに含まれる情報と、このパラメーター情報を検索して設定するメソッドを示します。

表 118. UserStoredProcedureParam オブジェクト内のパラメーター情報
パラメーター情報 UserStoredProcedureParam メソッド
パラメーター名 getParamName(), setParamName()
パラメーター値 getParamValue(), setParamValue()
パラメーターのデータ型
  • Java Object の場合

getParamDataTypeJavaObj(), setParamDataTypeJavaObj()
  • JDBC データ型の場合

getParamDataTypeJDBC(), setParamDataTypeJDBC()
パラメーターのイン/アウト・タイプ getParamIOType(), setParamIOType()
パラメーター・インデックスの位置 getParamIndex(), setParamIndex()

ストアード・プロシージャーにパラメーターを渡す手順は、以下のとおりです ストアード・プロシージャーにパラメーターを渡すには、以下の手順に従います。

  1. UserStoredProcedureParam オブジェクトを作成して、パラメーター情報を保持します。

    UserStoredProcedureParam() コンストラクターを使用して、新しい UserStoredProcedureParam オブジェクトを作成します。

    このコンストラクターに以下のパラメーター情報を渡すことにより、オブジェクトを初期化します。

  2. 各ストアード・プロシージャーのパラメーターについて、ステップ 1 を繰り返します。
  3. すべてのストアード・プロシージャーのパラメーターを保持するのに十分な要素を持つ Vector オブジェクトを作成します。
  4. 初期化された UserStoredProcedureParam オブジェクトをパラメーター Vector オブジェクトに追加します。

    Vector クラスの addElement() メソッドを使用して、UserStoredProcedureParam オブジェクトを追加します。

  5. すべての UserStoredProcedureParam オブジェクトを作成し、これらを Vector パラメーター配列に追加したら、このパラメーター配列を 2 番目の引き数として execStoredProcedure() メソッドに渡します。

    execStoredProcedure() メソッドにより、ストアード・プロシージャーとそのパラメーターがリレーションシップ・データベースへ送信され、実行されます。

注:
execStoredProcedure() の最初の引き数は、実行するストアード・プロシージャーの名前です。

例: 以下のように、get_empno() ストアード・プロシージャーが定義されているとします。

create or replace procedure get_empno(emp_id IN number,
       emp_number OUT number) as
    begin
       select emp_no into emp_number
       from emp
       where emp_id = 1;
    end;
 

このストアード・プロシージャーには、次の 2 つのパラメーターがあります。

例: 以下は、execStoredProcedure() メソッドを使用して get_empno() ストアード・プロシージャーを実行する例です。

DtpConnection connectn = null;
 try
    {
    // Get database connection
    connectn = getRelConnection("Customer");
  
    // Create parameter Vector
    Vector paramData = new Vector(2);
  
    // Construct the procedure name
    String sProcName = "get_empno";
  
    // Create IN parameter
    UserStoredProcedureParam arg_in = new UserStoredProcedureParam(
       1, "Integer", new Integer(6), "IN", "arg_in");
  
    // Create dummy argument for OUT parameter
    UserStoredProcedureParam arg_out = new UserStoredProcedureParam(
       2, "Integer", new Integer(0), "OUT", "arg_out");
  
    // Add these two parameters to the parameter Vector
    paramData.addElement(arg_in);
    paramData.addElement(arg_out);
  
    // Run get_empno() stored procedure
    connectn.execStoredProcedure(sProcName, paramData);
  
    // Get the result from the OUT parameter
    arg_out = (UserStoredProcedureParam) paramData.elementAt(1);
    Integer emp_number = (Integer) arg_out.getParamValue();
    }
 

ヒント:
Vector オブジェクトはゼロから始まる配列で、一方 UserStoredProcedureParam オブジェクトは 1 から始まる配列としてインデックスが付けられます。前述のコードでは、このパラメーター配列は 1 から始まるので、OUT パラメーターはインデックス値 2 で UserStoredProcedureParam() コンストラクターに作成されます。しかし、Vector パラメーター配列のこの OUT パラメーターの値にアクセスするには、この Vector 配列はゼロから始まるので、elementAt() 呼び出しでインデックス値 1 を指定します。

ストアード・プロシージャーは、そのパラメーターを SQL データ型として処理します。SQL と Java のデータ型は同一でない ため、マッピング API ではこれらの 2 つのデータ型の間でパラメーター値を変換する必要があります。IN パラメーターの場合、マッピング API ではパラメーター値を Java Object からその SQL データ型に変換します。OUT パラメーターの場合、マッピング API では SQL データ型から Java Object に変換します。マッピング API では、次の 2 つのデータ型マッピング層を使用して、これらの 2 つのデータ型の間でパラメーター値を変換します。

マッピング API では、JDBC データ型を内部で使用して、ストアード・プロシージャーとの間で送受信されるパラメーター値を保持します。JDBC は、java.sql.Types クラスで汎用 SQL タイプの ID の集合を定義します。 これらのタイプは、最も一般的に使用される SQL タイプを示します。また、JDBC には、JDBC タイプから Java データ型への標準マッピングも用意されています。例えば、通常、JDBC INTEGER は Java int タイプにマッピングされます。

IN (または INOUT) パラメーターを Java オブジェクトからそれに対応する JDBC にマップするために、マッピング API では 表 119 のマッピングを使用します。

表 119.
Java オブジェクトから対応する JDBC データ型へのマッピング
Java オブジェクトから JDBC データ型へ
String CHAR、VARCHAR、または LONGVARCHAR
java.math.BigDecimal NUMERIC
Boolean BIT
Integer INTEGER
Long BIGINT
Float REAL
Double DOUBLE
byte[] BINARY、VARBINARY、または LONGVARBINARY
java.sql.Date DATE
java.sql.Time TIME
java.sql.Timestamp TIMESTAMP
Clob CLOB
Blob BLOB
Array ARRAY
Struct STRUCT
Ref REF

OUT (または INOUT) パラメーターを JDBC データ型からそれに対応する Java オブジェクトにマップするために、マッピング API では表 120 のマッピングを使用します。

表 120.
JDBC データ型から Java オブジェクトへのマッピング
JDBC データ型から Java オブジェクトへ
CHAR、VARCHAR、LONGVARCHAR String
NUMERIC、DECIMAL java.math.BigDecimal
BIT Boolean
TINYINT Integer
SMALLINT Integer
INTEGER Integer
BIGINT Long
REAL Float
FLOAT、DOUBLE Double
BINARY、VARBINARY、または LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp
CLOB Clob
BLOB Blob
ARRAY Array
STRUCT Struct
REF Ref

したがって、すべての UserStoredProcedureParam オブジェクトには、表 121 に示すように、そのデータ型の 2 つの表現が含まれます。

表 121. パラメーターのデータ型
パラメーターのデータ型 説明 UserStoredProcedureParam メソッド
Java Object マップ変換コードでパラメーター値を保持するために使用されるデータ型 getParamDataTypeJavaObj(), setParamDataTypeJavaObj()
JDBC データ型 マッピング API でパラメーター値を保持するために内部で使用されるデータ型 getParamDataTypeJDBC(), setParamDataTypeJDBC()

表 121UserStoredProcedureParam メソッドを使用して、いずれかの形式のパラメーター・データ型にアクセスできます。ただし、次の理由から、Java Object データ型 (IntegerString、または Float など) を使用する必要があります。

get_empno()emp_id パラメーターは、整数値を含む、NUMBER の SQL データ型で宣言されます。したがって、*** で開始するコード例では、emp_id パラメーター (インデックス位置 1 のパラメーター) の UserStoredProcedureParam() 呼び出しにより、次の 3 番目の引き数でその値が 6 に設定されます。

new Integer(6)
 

この呼び出しでは、次の 2 番目の引き数でパラメーターのタイプが同じ Java Object タイプにも設定されます。

"Integer"
 

接続のクローズ

リレーションシップ・データベースへの接続は、マップの実行が完了すると解放されます。

マップが正常に実行されると、すべてのトランザクションは、明示的にコミットされていなくても、自動的にコミットされます。 マップの実行が失敗すると (例えば、catch ステートメントによって処理されない例外がスローされる場合)、すべてのトランザクションは、明示的にロールバックされなくても、ロールバックされます。

Copyright IBM Corp. 2004