• 検索結果がありません。

ストラドプロシージャの呼び出し方

N/A
N/A
Protected

Academic year: 2021

シェア "ストラドプロシージャの呼び出し方"

Copied!
26
0
0

読み込み中.... (全文を見る)

全文

(1)

ス ト ア ド プ ロ シージ ャの

呼び出 し 方

こ の機能は、 Release10.5 以降で利用可能です。

Oracle、 DataServer、 Informix、 MS SQL デー タ ベース を使用 し て い る場合、 NXJ ア プ リ ケーシ ョ ンか ら ス ト ア ド プ ロ シージ ャ の呼び出 し 、 準備、 実行を簡単に行え る埋込み型 SQL を利用する こ と がで き ます。 ネ イ テ ィ ブの JDBC 構文の場合 と は 違 っ て、 ス ト ア ド プ ロ シージ ャ の呼び出 し (ス ト ア ド フ ァ ン ク シ ョ ン お よ びス ト ア ド パ ッ ケージ も 同様) には、 追加の Java プ ロ グ ラ ミ ン グ を必要 と し ません。 し か し なが ら 、 JDBC 構文のネ イ テ ィ ブ なサポー ト も 、 NXJ 環境内で行 っ ています。 (注 : 他のデー タ ベースに対する NXJ ス ト ア ド プ ロ シージ ャのサポー ト は、 将来の リ リ ースにおいて追加 さ れます。)

構文の呼び出 し

ス ト ア ド プ ロ シージ ャ ま たはス ト ア ド フ ァ ン ク シ ョ ンは、 コ ンパ イル時に利用可 能であ り 、 メ タ デー タ は JDBC ド ラ イバか ら 取得で き なければな り ません。 ス ト ア ド プ ロ シージ ャ / フ ァ ン ク シ ョ ン を実行する ために、 NXJ プ ロ グ ラ ミ ン グ 言語ス ク リ プ ト で以下の構文を使用 し ます。

EXEC SQL [USING CONNECTION <connection-name>]

CALL [<schema-name>.][<package-name>.]<function-name> ([<argument-list>]) [RETURNING <return-variable> ] [INTO <result-set>|<object-array>|<variable-list> ( ;| EXECUTING { <code-statements> } ) ]

(2)

1 CALL文の引数 (1 of 2)

構文のエ レ メ ン ト 説明

USING CONNECTION <connection-name>

ス ト ア ド プ ロ シージ ャ が実行 さ れる接続の名前を指定 し ます。 CALL [<schema-name>.][<package-name>.]<function-name> 実行する ス ト ア ド フ ァ ン ク シ ョ ンの名前を指定 し ます。 スキーマ名はオ プ シ ョ ン です。 指定 し ない場合は、 指定 さ れた接続のデ フ ォル ト スキーマが使用 さ れます (使用 し てい るデー タ ベースのベ ン ダーが定義する)。 プ ロ シージ ャ が Oracle パ ッ ケージの中で定義 さ れている場 合、 プ ロ シージ ャ 名にはそのパ ッ ケージ名が指定 さ れな ければな り ません。 <argument-list> ス ト ア ド フ ァ ン ク シ ョ ンのためのに カ ン マ で区切 ら れた 引数の リ ス ト です。 引数の数お よび タ イ プは、 ス ト ア ド フ ァ ン ク シ ョ ン で定義 さ れてい る も の と 一致 し なければ な り ません。 IN パ ラ メ ー タ は、 Java 式の可能性があ り 、 OUT お よ び IN OUT パ ラ メ ー タ は、 変数 リ フ ァ レ ン ス で なければな り ません。 RETURNING <return-variable> 戻 さ れた値を受け取る ための変数を指定 し ます。 一般的 に、 こ の句は リ ザル ト セ ッ ト で ない戻 り 値を扱 う ために 使用 さ れます。 RETURNING 句が指定 さ れて、 <return-variable> が リ ザル ト セ ッ ト で あ る場合、 INTO 句が指定 さ れる こ と はあ り ません (指定 し た場合、 コ ンパ イルエ ラ ーにな り ます)。 Informix ス ト ア ド プ ロ シージ ャ では、 RETURNING 句は 使え ません。 INTO 句を使わなければな り ません。

(3)

注 – リ ザル ト セ ッ ト を処理する には、 INTO <variable-list> EXECUTING 構文を使 用す る こ と を推奨 し ます。

注 – Oracle を除 く 、 ほ と んどの JDBC ド ラ イバは リ ザル ト セ ッ ト の処理が終わる ま で、 ス ト ア ド プ ロ シージ ャ / ス ト ア ド フ ァ ン ク シ ョ ンの戻 り 値 と OUT パ ラ メ ー タ を更新 し ません。 ス ト ア ド プ ロ シージ ャ が OUT と RETURN <result-set> の両方 を持つ場合、 OUT 値は EXECUTING 句で利用で き ません。

INTO <result-set>|<object-array>|<variable-list>

一般的に、 INTO <object-array>|<variable-list> 句は、 ス ト ア ド プ ロ シージ ャ か ら 戻 さ れた値を処理する ために、 EXECUTING 句 と と も に使用 さ れます。 INTO <result-set> の値が リ ザル ト セ ッ ト の場合、 EXECUTING 句は使 用する こ と がで き ません。 INTO の値が リ ザル ト セ ッ ト の場合、 EXEC SQL ITERATE <result-set> 句が使用 さ れ なければな り ません (下記の構文を参照 し て く だ さ い)。 INTO <result-set> の使用は、 戻 さ れた変数が リ ザル ト セ ッ ト であ る RETURNING <return-variable> の使用 と 機 能的に等 し く な り ます。 INTO 句に、 Object[] 変数や変数の リ ス ト を指定 し て、 EXECUTING 句が指定 さ れない場合は、 リ ザル ト セ ッ ト の最初の行のデー タ 値が、 Object[] 変数ま たは変数の リ ス ト に割 り 当て ら れます。 Object[] に行の値を入力す る場合、 NXJ は リ ザル ト セ ッ ト の列数に等 し い長 さ で新 し い Object[] を割 り 当て ま す。 イ ンデ ッ ク ス 0 は、 1 つ目の列の値に割 り 当て られ、 イ ンデ ッ ク ス 1 は、 2 つ目の列の値に割 り 当て られます。 変数 リ ス ト に行の値を入力する場合、 1 つ目の変数は、 1 つ目の列の値に割 り 当て ら れ、 2 つ目の変数は、 2 つ目 の列の値に割 り 当て ら れます。 リ ス ト の変数の数 と タ イ プが リ ザル ト セ ッ ト の列 と 一致 し ていない場合、 ラ ン タ イ ム例外が発生する こ と に注意 し て く だ さ い。 EXECUTING { <code-statements> } リ ザル ト セ ッ ト の各行のために、 一旦、 実行 さ れる コ ー ド 文のブ ロ ッ ク を指定 し ます。 表1 CALL文の引数 (2 of 2) 構文のエ レ メ ン ト 説明

(4)

デー タ ベースが リ ザル ト セ ッ ト を処理する前に行 う OUT パ ラ メ ー タ 受け渡 し をサ ポー ト する場合、 リ ザル ト セ ッ ト を処理す る前に (つま り 、 あ ら ゆる コ ー ド 文を 実行する前) OUT 変数を割 り 当て る ために以下を行 う こ と がで き ます。

例 : Process RETURN カー ソルに INTO <variable list> を使用

//stock_price is an AMOUNT field type

// or a variable

// function that has one IN (NUMERIC) and output // cursor with 3 columns

// String, Amount and Date

EXEC SQL CALL hr.sp_get_stocks(stock_price) INTO ric,price,spupdated

EXECUTING {

// populating single multi_valued field “nraise” // a non-target selected set

// on Data View “dataview1” dataview1.clearToAdd(); dataview1.nraise = ric + " " + price.toString() + " " + spupdated.toString(); dataview1.updateCurrentRecord(); } 以下のス ト ア ド フ ァ ン ク シ ョ ンの例は カ ー ソ ルを戻 し ます。

CREATE OR REPLACE FUNCTION "HR"."SP_GET_STOCKS" (v_price IN NUMBER)

RETURN Types.ref_cursor AS

stock_cursor types.ref_cursor; BEGIN

OPEN stock_cursor FOR

SELECT ric,price,updated FROM stock_prices WHERE price < v_price;

RETURN stock_cursor; END;

(5)

例 : IN と OUT パラ メ ー タ

EXEC SQL CALL HR.EMPLOYEE_PKG.GetEmployeeDetails

(1,em_first_name,em_last_name,em_salary,em_start_date); session.displayToMessageBox("Response: " + em_first_name + " " + em_last_name + " " + em_salary + " " + em_start_date); 以下のス ト ア ド プ ロ シージ ャ の例は、 IN パ ラ メ ー タ と OUT パ ラ メ ー タ を使用 し ます。 PROCEDURE GetEmployeeDetails( i_emID INemployee.em_id%TYPE,

o_FirstName OUT employee.em_first_name%TYPE, o_LastNameOUTemployee.em_last_name%TYPE, o_SalaryOUTemployee.em_salary%TYPE, o_StartDateOUTemployee.em_start_date%TYPE) IS BEGIN SELECT em_first_name, em_last_name, em_salary, em_start_date INTO o_FirstName, o_LastName, o_Salary, o_StartDate FROM employee

WHERE em_id = i_emID; END GetEmployeeDetails;

リ ザル ト セ ッ ト は ITERATE 句で ト ラバースする

以下の構文は、 OUT パ ラ メ ー タ と し て 1 つ以上の リ ザル ト セ ッ ト を持つプ ロ シー ジ ャ を実行する と き に参考にな り ます。 EXEC SQL ITERATE <resultset-variable-name>

(6)

EXECUTING { <code-statements> } ) 構文引数の説明については、2 ページの表 1 「CALL 文の引数」 を参照 し て く だ さ い。

以下の例は、 ITERATE で RETURNING <result-set> カ ー ソルを使用 し ます。 // Variables defined on Form

// NullableStringVariable ric; // NullableAmountVariable price; // NullableDateVariable spupdated; // Declare ResultSet “rs” for RETURNING ResultSet rs;

EXEC SQL CALL HR.sp_get_stocks(stock_price) RETURNING rs;

// Iterate through the returned result set EXEC SQL ITERATE rs

INTO ric,price,spupdated EXECUTING

{

// populating single multi_valued field “nraise” // a non-target selected set

// on Data View “dataview1” dataview1.clearToAdd(); dataview1.nraise = ric + " " + price.toString() + " " + spupdated.toString(); dataview1.updateCurrentRecord(); }

(7)

ダ イ ナ ミ ッ ク ス ト ア ド プ ロ シージ ャ

多 く のス ト ア ド プ ロ シージ ャ は、 動的に実行時に準備、 実行 さ れる必要があ り ま す。

例えば、 OUT パ ラ メ ー タ と し て Oracle INDEX BY TABLE を使用する場合、 文は ダ イ ナ ミ ッ ク 構文を使用 し て準備 さ れなければな り ません。 こ れに よ り 、 IN と OUT パ ラ メ ー タ を設定、 取得が可能にな り ます。 Dynamic パ ラ メ ー タ の詳細 と 構 文に関 し ては、 NXJ Javadoc の NXJParameter を参照 し て く だ さ い。

注 – INDEX BY TABLE の OUT パ ラ メ ー タ を持つ Oracle のダ イ ナ ミ ッ ク ス ト ア ド プ ロ シージ ャ の使用は、 OCI JDBC イ ン タ フ ェ ースの使用を必要 と し ます。 OCI イ ン タ フ ェ ース を使用する には、 ア プ リ ケーシ ョ ンサーバ上に Oracle ク ラ イ ア ン ト の イ ン ス ト ールが必要にな り ます。

構成 :

Type: Other JDBC Databases

Jar/Zip File: C:¥Unify¥NXJ¥lib¥jdbcDrivers¥ojdbc14.zip User Name: xxxxx Password : xxxx

Driver: odbc.jdbc.driver.OracleDriver URL: jdbc:oracle:oci:@servername

“servername” は、 Oracle Network Client で構成 さ れな ければな り ません。

PREPARE CALL 構文

PREPARE CALL 文は、 以下の構文 を持 ち ます。

EXEC SQL [ USING CONNECTION <connection-name> ] PREPARE CALL <string-expression>

(8)

NXJPreparedCall myCall;

EXEC SQL USING CONNECTION ociOracle PREPARE CALL "HR.EMPLOYEE_PKG.GetEmployeeList" INTO myCall;

注 – EXEC SQL EXECUTE 文を呼び出す前に、 registerIndexTableOutParameter() 呼 び出 し を使用 し て OUT パ ラ メ ー タ を登録 し なければな り ません。 未登録の PL/SQL イ ン デ ッ ク ス テ ーブル OUT パ ラ メ ー タ があ る場合、 EXEC SQL EXECUTE 文は、 SQLException を ス ロー し ます。

// Get the NXJ Parameters for the prepared call NXJParameter[] params = myCall.getOutputParameterData(); // you must register the estimated array size

// value for each parameter in this example there are 3 OUT parameters.

params[0].registerIndexTableOutParameter(100); 表2 PREPARE CALL文の引数

構文エ レ メ ン ト 説明

USING CONNECTION <connection-name>

ス ト ア ド プ ロ シージ ャ が実行 さ れる接続名。 CALL <string-expression> ス ト ア ド プ ロ シージ ャ の名前の文字列式。 実行時にス ト ア ド プ ロ シージ ャ の メ タ デー タ が明 ら かに取得で き ない 場合、 例外がス ロー さ れます。 INTO <NXJPreparedCall> メ タ デー タ 情報の ク エ リ 、 お よびス ト ア ド プ ロ シージ ャ を実行する ためのハン ド ルを提供する NXJPreparedCall 変数。

(9)

params[1].registerIndexTableOutParameter(100); params[2].registerIndexTableOutParameter(100);

EXECUTE 構文

ス ト ア ド プ ロ シージ ャ が準備 さ れて、 OUT パ ラ メ ー タ が登録 さ れた後、 ス ト ア ド プ ロ シージ ャ は以下の構文を使用 し て実行す る こ と がで き ます。 EXEC SQL EXECUTE <NXJPreparedCall> [ USING (<input-object-array>|<expression-list>) [ RETURNING (<result-set>|<output-object-array.| <variable-list>) ; 表3 EXECUTE 文の引数 構文エ レ メ ン ト 説明 EXECUTE <NXJPreparedCall> 実行する NXJPreparedCall を指定 し ます。 USING (<input-object-array>|<expression-list>) ス ト ア ド プ ロ シージ ャ の IN パ ラ メ ー タ に値を提供する ために使用 し ます。 Object[] が提供 さ れる場合、 各 IN パ ラ メ ー タ ご と に 1 つのエ レ メ ン ト がなければな り ませ ん。 カ ン マ で区切 ら れた式の リ ス ト が提供 さ れる場合、 各 IN パラ メ ー タ ご と に 1 つの式がなければな り ません。 INTO (<result-set>|<output-object-array>|<variable-list>) ス ト ア ド プ ロ シージ ャ の OUT パ ラ メ ー タ 用の値を ど こ に置 く かを指定する ために使用 し ます。 変数の リ ス ト の場合、 ス ト ア ド プ ロ シージ ャ か ら 戻 さ れ る各 OUT パラ メ ー タ ご と に 1 つの変数がなければな り ません。 変数の数 と タ イ プは、 ス ト ア ド プ ロ シージ ャ か ら の出力に一致 し なければな り ません。 さ も なければ、 ラ ン タ イ ム例外がス ロー さ れます。 変数の リ ス ト は、 リ ザル ト セ ッ ト 変数を含みます。

(10)

Object[] が指定 さ れる場合、 NXJ は OUT パ ラ メ ー タ の数に等 し い長 さ で新 し い Object[] を割 り 当て ます。 イ ン デ ッ ク ス 0 は、 1 つ目の OUT パ ラ メ ー タ の値に割 り 当て ら れます。 イ ン デ ッ ク ス 1 は、 2 つ目の OUT パ ラ メ ー タ の値に割 り 当て ら れます。 ス ト ア ド プ ロ シージ ャ が戻 り 値を持つ場合、 最初の OUT パ ラ メ ー タ が割 り 当て ら れる と 考え ら れます。

PREPARE のサン プルス ト ア ド プ ロ シージ ャ 。 // Package

TYPE tblEMID IS TABLE OF NUMBER(3)INDEX BY BINARY_INTEGER;

TYPE tblFirstName IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER; TYPE tblLastName IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER; TYPE tblSalary IS TABLE OF NUMBER(6) INDEX BY BINARY_INTEGER; TYPE tblStartDate IS TABLE OF DATE INDEX BY BINARY_INTEGER; PROCEDURE GetEmployeeList(

o_emID OUT tblEMID,

o_FirstName OUT tblFirstName, o_LastNameOUTtblLastName) // Package Body

PROCEDURE GetEmployeeList( o_emID OUT tblEMID, o_FirstNameOUT tblFirstName, o_LastNameOUTtblLastName) IS

CURSOR employee_cur IS

SELECT em_id,em_first_name, em_last_name FROM employee;

recCount NUMBER DEFAULT 0; BEGIN

FOR EmployeeRec IN employee_cur LOOP recCount:= recCount + 1; o_emID(recCount):= EmployeeRec.em_id; o_FirstName(recCount):= EmployeeRec.em_first_name; o_LastName(recCount):= EmployeeRec.em_last_name; END LOOP; END GetEmployeeList;

(11)

EXEC SQL PREPARE CALL を使用す る NXJ 例。

// using TABLE INDEX BY return values:

// i.e. TYPE tblEMID IS TABLE OF NUMBER(3)INDEX BY BINARY_INTEGER; // NOTE: Oracle TABLE INDEX BY requires the OCI JDBC connection // which requires the Oracle Client be installed on the

// Application Server. // Configuration is:

// Type: Other JDBC Databases

// Jar/Zip File: C:¥Unify¥NXJ¥lib¥jdbcDrivers¥ojbdbc14.jar // User Name: xxxxx Password : xxxx

// Driver: odbc.jdbc.driver.OracleDriver // URL: jdbc:oracle:oci:@servername

// NOTE: This server MUST be configured in the Oracle Network // Client

// Define the NXJ Prepared Call NXJPreparedCall call;

EXEC SQL USING CONNECTION ociOracle PREPARE CALL "HR.EMPLOYEE_PKG.GetEmployeeList" into call;

// Get the NXJ Parameters for the prepared call NXJParameter[] params = call.getOutputParameterData(); // you must register the estimated array size

// value for each parameter

params[0].registerIndexTableOutParameter(100); params[1].registerIndexTableOutParameter(100); params[2].registerIndexTableOutParameter(100); // Define variables for the return values

int[] firstArray; String[] secondArray; String[] thirdArray; // Execute the call

EXEC SQL EXECUTE call RETURNING firstArray, secondArray, thirdArray;

// Loop through the returned arrays and in this example // add them to a selected set.

for (int i = 0; i < firstArray.length; i++) {

(12)

testview1.updateCurrentRecord(); }

// Close the prepared call call.close();

ダ イ ナ ミ ッ ク パラ メ ー タ

NXJPreparedCall と NXJParameter は、 事前に準備 さ れた文で利用 さ れ る ク エ リ ス ト ア ド プ ロ シージ ャ メ タ デー タ に イ ン タ フ ェ ース を提供す る NXJ ク ラ ス です。 これ ら の イ ン タ フ ェ ースは、 以下の メ ソ ッ ド を定義 し ます。 NXJPrepreparedCall NXJPreparedCall Void close() 例 : NXJPrepareCall sp_call; Sp_call.close(); NXJParameter[] getInputParameterData NXJParameter[] getInputParameterData() throws SQLException; ス ト ア ド プ ロ シージ ャ への入力パ ラ メ ー タ の メ タ デー タ を取得 し ます。 例 :

(13)

NXJParameter[] getOutputParameterData NXJParameter[] getOutputParameterData() throws SQLException; ス ト ア ド プ ロ シージ ャ の出力パ ラ メ ー タ の メ タ デー タ を取得 し ます。 プ ロ シー ジ ャ が戻 り 値を持つ場合、 配列の最初のエ レ メ ン ト がその メ タ デー タ を提供 し ま す。 ス ト ア ド プ ロ シージ ャ が暗黙的な リ ザル ト セ ッ ト を返す場合、 配列の最初の エ レ メ ン ト がその メ タ デー タ を提供 し ます。 ス ト ア ド プ ロ シージ ャ が暗黙的な リ ザル ト セ ッ ト と 整数の戻 り 値の両方を持つ場合、 暗黙的な リ ザル ト セ ッ ト は最初 のエ レ メ ン ト がその メ タ デー タ を提供 し ます。 整数の戻 り 値 (getVendorReturnCode() によ っ て取得で き る) があ るかど う かを決定する ために、 hasVendorReturnCode() を使用 し ま す。 hasVendorReturnCode() boolean hasVendorReturnCode(); こ の NXJPreparedCall イ ン ス タ ン スが、 暗黙的な リ ザル ト セ ッ ト と 整数の戻 り 値の 両方を返すス ト ア ド プ ロ シージ ャ を呼び出す場合、 true を返 し ます。 getVendorReturnCode () int getVendorReturnCode(); ス ト ア ド プ ロ シージ ャ のために整数の戻 り 値を返 し ます。 hasVendorReturnCode() が false を返す場合、 IllegalStateException を ス ロー し ます。 NXJParameter 以下の メ ソ ッ ド は、 メ タ デー タ 情報のためにあ り ます。 String getName(); - パ ラ メ ー タ の名前 を得ま す。 int getSqlType();

(14)

- パ ラ メ ー タ の java sql タ イ プ を得ま す。 int getExtendedType(); パ ラ メ ー タ の拡張 さ れた タ イ プ を得ます。 標準 タ イ プの場合、 NXJExtendedSQLType.NOT_EXTENDED が返 さ れます。 String getTypeName(); - デー タ ベース に識別 さ れて い る タ イ プ名 を得ます。 int getLength(); - こ のパ ラ メ ー タ が保持で き る デー タ のバ イ ト 長 を得ま す。 intgetNullable(); - 以下の内の 1 つが返 り ます。 NXJParameter.NO_NULLS NXJParameter.NULLABLE NXJParameter.NULLABLE_UNKNOWN intgetPrecision(); - パ ラ メ ー タ の精度 を得ます。 shortgetRadix(); - パ ラ メ ー タ の基数 を得ます。 shortgetScale(); - パ ラ メ ー タ のス ケール を得ま す。 以下の メ ソ ッ ド は、 Oracle の PL/SQL イ ンデ ッ ク ス テーブル用の ものであ り 、 OUT パ ラ メ ー タ が PL/SQL イ ン デ ッ ク ス テー ブルの場合にのみ使用す る こ と がで き ます。 つま り 、 OUT パ ラ メ ー タ の NXJParameter.getExtenedType() は、 NXJExtentedSQLTypes.INDEX_BY_TABLE を返 し ます。 int getIndexTableElemSqlType(); - イ ン デ ッ ク ス テー ブル内で エ レ メ ン ト の sql タ イ プ を得ます。 int getIndexTableElemMaxLen();

(15)

- イ ン デ ッ ク ス テー ブル内で エ レ メ ン ト の最大の長 さ を得ま す。

エ レ メ ン ト sql タ イ プが VARCHAR, CHAR, BINARY で ない場合、 こ の値は 0 で す。

registerOracleArrayOutParameter

registerOracleArrayOutParameter() は、 OUT Oracle 配列パ ラ メ ー タ 毎に呼び出 さ れ なければな り ません。 こ れ ら の配列は、 Oracle Array タ イ プの “User Types-> Array Types” です。 例 : outputParameterData[0].registerOracleArrayOutParameter("MY_ARRAY"); registerIndexTableOutParameter registerIndexTableOutParameter() メ ソ ッ ド は、 NXJParameter.getExtenedType() メ ソ ッ ド が NXJExtentedSQLTypes.INDEX_BY_TABLE を返すすべての OUT パ ラ メ ー タ 毎 に呼び出 さ れなければな り ません。 NXJ が EXEC SQL EXECUTE 文を処理する と き、 未登録の イ ン デ ッ ク ス テーブル OUT パ ラ メ ー タ がある場合、 SQLException を ス ロ ー し ます。

void registerIndexTableOutParameter( int maxLen );

int maxLen - こ れは、 配列の最大サ イ ズが返 さ れ る こ と を示 し ます。 NXJParameter につい ての詳細は、 Javadoc を参照 し て く だ さ い。 こ の イ ン タ フ ェ ースは、 NXJ に よ っ てサポー ト さ れる標準ではない SQL タ イ プ を 定義 し ます。 こ れ ら の値は、 NXJParameter.getExtendedType() によ っ て返 さ れます。 こ の リ リ ースには、 以下の拡張 さ れた タ イ プがあ り ます。 NOT_EXTENDED - NXJParameter が、 NXJ に よ っ てサポー ト さ れる拡張 さ れた SQL タ イ プ では ない こ と を示 し ます。 ユーザは、 パ ラ メ ー タ タ イ プ を識別する ために、 NXJParameter.getSqlType() を使用す る必要があ り ま す。 RESULT_SET - NXJParameter が、 ResultSet であ る こ と を示 し ます。

(16)

- NXJParameter が、 Oracle PL/SQL イ ン デ ッ ク ス テー ブルで あ る こ と を示 し ま す。

例 :

NXJPreparedCall sp_call;

EXEC SQL USING CONNECTION ociOracle

PREPARE CALL "HR.EMPLOYEE_PKG.GetEmployeesAboveSalary" INTO sp_call;

NXJParameter[] inparams = sp_call.getInputParameterData(); session.displayToMessageBox("input: " +

inparams[0].getSqlType());

NXJParameter[] outparams = sp_call.getOutputParameterData(); for (int index = 0; index < outparams.length; index++) {

NXJParameter outparam1 = outparams[index];

session.displayToMessageBox(" OUT: " + param1.getName() + " Type: " + outparam1.getIndexTableElemSqlType()); if (outparam1.getExtendedType() == com.unify.nxj.mgr.dataConnection.NXJExtendedSQLTypes.INDEX_BY_TABLE) { outparam1.registerIndexTableOutParameter(1000); } }

// Define variables for the return values int[] o_emID; int myinput = 10000; String[] o_FirstName; String[] o_lastName; float[] o_Salary; java.sql.Timestamp[] o_startDate;

グローバル変数

以下のよ う に、 パ ッ ケージのグ ロ ーバル変数 (特にオ ラ ク ル) にア ク セ スす る こ と がで き ます。

EXEC SQL [ USING CONNECTION <connection-name> ] GET VAR <string-expression>

(17)

以下のよ う に、 パ ッ ケージのグ ロ ーバル変数 (特にオ ラ ク ル) を設定 し ます。 EXEC SQL [ USING CONNECTION <connection-name> ]

SET VAR <string-expression> USING <input-expression>; 注 – コ ンパ イル時には、 グ ローバル変数の存在有無、 ま たはグ ローバル変数 と ホ ス ト 変数 タ イ プ間のデー タ タ イ プの不整合を チ ェ ッ ク す る こ と がで き ません。 代 わ り に、 こ れ ら のエ ラ ー状況は、 ラ ン タ イ ム例外に終わる で し ょ う 。 従 っ て、 こ のよ う な エ ラ ーの場合には実行時の例外が発生 し て し まいます。 例 :

// As defined in Oracle Package: EMPLOYEE_PKG 表4 GET VAR 文引数

構文エ レ メ ン ト 説明

GET VAR <string-expression>

戻 さ れるパ ッ ケージ変数 (例えば、 "MY_PACKAGE.MY_VARIABLE") を識別す る文字列式。 INTO <return-variable> 戻 さ れる変数。 表5 SET VAR文引数 構文エ レ メ ン ト 説明

SET VAR <string-expression>

設定 さ れるパ ッ ケージ変数 (例えば、

"MY_PACKAGE.MY_VARIABLE") を識別す る文字列 式。

USING <input-expression>

(18)

EXEC SQL

SET VAR "HR.EMPLOYEE_PKG.myString" USING setfield;

EXEC SQL

GET VAR "HR.EMPLOYEE_PKG.myString" INTO setfield; session.displayToMessageBox(setfield);

Oracle の raise_application_error()

Oracle のス ト ア ド プ ロ シージ ャ が、 raise_application_error() を呼び出す と きは常に、 Oracle JDBC ド ラ イ バに よ っ て ス ロ ー さ れて い る SQLException で終わ り ます。 例 外 メ ッ セージは、 詳細な メ ッ セージ を提供 し ます。 SQLException.getErrorCode() を 使 っ て、 raise_application_error() に渡 さ れる エ ラ ー コ ー ド を取得する こ と がで き ま す。

その他の Oracle 例

Oracle ス ト ア ド プ ロ シージ ャ と の間でデー タ を受け渡 し す る 1 つの方法 と し て、 カ ー ソ ルを利用す る こ と がで き ます。 カ ー ソ ル変数の PL/SQL タ イ プは、 REF CURSOR です。 例 :

CREATE OR REPLACE PACKAGE types AS

TYPE ref_cursor IS REF CURSOR; END; カ ー ソ ルは、 1 つ以上の行を返す SQL 文の作業領域です。 それは、 リ ザル ト セ ッ ト か ら 1 つずつ行を フ ェ ッ チする こ と を可能に し ます。 カ ー ソルの使用は特に難 し い こ と はあ り ませんが、 PL/SQL ス ト ア ド プ ロ シージ ャ か ら リ ザル ト セ ッ ト を返 すために カ ー ソ ル変数を使用 し なければな り ません。 カ ー ソ ル変数は、 基本的に カ ー ソ ルのポ イ ン タ なので、 ス ト ア ド プ ロ シージ ャ へのパ ラ メ ー タ のよ う に、 カ ー ソ ルその も のではあ り ませんがその リ フ ァ レ ン ス と し て同様に扱 う こ と がで き ます。

(19)

NXJ の 2 つの異な る方法で PL/SQL カ ー ソ ル を利用す る こ と がで き ます。 1 つ目 は、 自動的に NXJ 変数に カ ー ソルの列の割 り 当て を行ないます。 2 つ目は、 NXJ

リ ザル ト セ ッ ト に カ ー ソ ルを割 り 当て た後に、 リ ザル ト セ ッ ト に よ っ て割 り 当て を繰 り 返すか、 さ も なければ カ ー ソ ルの列を直接操作 し ます。

Oracle ス ク リ プ ト

CREATE TABLE STOCK_PRICES( RIC VARCHAR(6) PRIMARY KEY, PRICE NUMBER(7,2),

UPDATED DATE ) TABLESPACE USERS /

INSERT INTO STOCK_PRICES(RIC, PRICE, UPDATED) VALUES('MSFT', 69.20, SYSDATE)

/

INSERT INTO STOCK_PRICES(RIC, PRICE, UPDATED) VALUES('RSAS', 30.18, SYSDATE)

/

INSERT INTO STOCK_PRICES(RIC, PRICE, UPDATED) VALUES('AMZN', 15.50, SYSDATE)

/

INSERT INTO STOCK_PRICES(RIC, PRICE, UPDATED) VALUES('SUNW', 16.25, SYSDATE)

/

INSERT INTO STOCK_PRICES(RIC, PRICE, UPDATED) VALUES('ORCL', 14.50, SYSDATE)

/ COMMIT /

CREATE OR REPLACE PACKAGE Types AS

TYPE ref_cursor IS REF CURSOR; END;

/

CREATE OR REPLACE FUNCTION sp_get_stocks(v_price IN NUMBER) RETURN types.ref_cursor

AS

stock_cursor types.ref_cursor; BEGIN

(20)

WHERE price < v_price; RETURN stock_cursor; END;

NXJ コ マ ン ド

COMMAND sp_get_stocks {

//stock_price is an AMOUNT field type or a variable

// Variables “ric”,”price”, and “spupdated” are defined as // NullableStringVariable ric;

// NullableAmountVariable price; // NullableDateVariable spupdated;

EXEC SQL CALL hr.sp_get_stocks(stock_price) INTO ric,price,spupdated

EXECUTING {

session.displayToMessageBox(": " + ric + " " + price + " " + spupdated);

} }

COMMAND sp_get_stocks2 {

DataViewHelper.clearSet(testview1); // this is just clearing out the selected set

// Define the Result Set ResultSet rs;

EXEC SQL CALL HR.sp_get_stocks(stock_price) // NOTE: Can also use RETURNING rs;

INTO rs;

// Iterate through the returned result set EXEC SQL ITERATE rs

INTO ric,price,spupdated EXECUTING

{

testview1.clearToAdd();

testview1.nraise = ric + " " + price.toString() + " " + spupdated.toString();

testview1.updateCurrentRecord(); }

(21)

}

Oracle INDEX_BY_TABLE : パ ッ ケージ ス ク リ プ ト

CREATE OR REPLACE PACKAGE "HR"."EMPLOYEE_PKG" AS TYPE tblEMID IS TABLE OF NUMBER(3) INDEX BY BINARY_INTEGER;

TYPE tblFirstName IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;

TYPE tblLastName IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;

TYPE tblSalary IS TABLE OF NUMBER(6) INDEX BY BINARY_INTEGER;

TYPE tblStartDate IS TABLE OF DATE INDEX BY BINARY_INTEGER;

myNumber NUMBER; myString VARCHAR2(40); PROCEDURE GetEmployeeList(

o_emID OUT tblEMID, o_FirstName OUT tblFirstName, o_LastName OUT tblLastName); PROCEDURE GetEmployeesAboveSalary(

i_MinimumSalary INemployee.em_salary%TYPE, o_emID OUT tblEMID,

o_FirstName OUT tblFirstName, o_LastNameOUTtblLastName, o_SalaryOUTtblSalary);

/******************************************************************* * Retrieves a single employees details using standard arguments

*******************************************************************/ PROCEDURE GetEmployeeDetails(

i_emID INemployee.em_id%TYPE,

o_FirstName OUT employee.em_first_name%TYPE, o_LastNameOUTemployee.em_last_name%TYPE,

(22)

END Employee_Pkg;

Oracle INDEX_BY_TABLE: パ ッ ケージボデ ィ ス ク リ プ ト

CREATE OR REPLACE PACKAGE BODY "HR"."EMPLOYEE_PKG" AS PROCEDURE GetEmployeeList(

o_emID OUT tblEMID, o_FirstName OUT tblFirstName, o_LastName OUTtblLastName) IS

CURSOR employee_cur IS

SELECT em_id,em_first_name, em_last_name FROM employee;

recCount NUMBER DEFAULT 0; BEGIN

FOR EmployeeRec IN employee_cur LOOP recCount := recCount + 1; o_emID(recCount) := EmployeeRec.em_id; o_FirstName(recCount):= EmployeeRec.em_first_name; o_LastName(recCount) := EmployeeRec.em_last_name; END LOOP; END GetEmployeeList; PROCEDURE GetEmployeesAboveSalary( i_MinimumSalary INemployee.em_salary%TYPE, o_emID OUT tblEMID,

o_FirstName OUT tblFirstName, o_LastNameOUTtblLastName,

o_SalaryOUTtblSalary) IS

CURSOR employee_cur (curMinSalary NUMBER) IS SELECT em_id,

em_first_name, em_last_name, em_salary, em_start_date FROM employee

WHERE em_salary > curMinSalary; recCount NUMBER DEFAULT 0;

(23)

FOR EmployeeRec IN employee_cur(i_MinimumSalary) LOOP recCount:= recCount + 1; o_emID(recCount) := EmployeeRec.em_id; o_FirstName(recCount):= EmployeeRec.em_first_name; o_LastName(recCount) := EmployeeRec.em_last_name; o_Salary(recCount) := EmployeeRec.em_salary; END LOOP; END GetEmployeesAboveSalary; /******************************************************************* * Retrieves a single employees details using standard arguments

*******************************************************************/ PROCEDURE GetEmployeeDetails(

i_emID INemployee.em_id%TYPE,

o_FirstName OUT employee.em_first_name%TYPE, o_LastName OUTemployee.em_last_name%TYPE, o_Salary OUTemployee.em_salary%TYPE, o_StartDate OUTemployee.em_start_date%TYPE) IS BEGIN SELECT em_first_name, em_last_name, em_salary, em_start_date INTO o_FirstName, o_LastName, o_Salary, o_StartDate FROM employee

WHERE em_id = i_emID; END GetEmployeeDetails; END Employee_Pkg;

NXJ コ マ ン ド

// ********************** GetEmployeeList ********************* // Define the NXJ Prepared Call

(24)

// Get the NXJ Parameters for the prepared call NXJParameter[] params = call.getOutputParameterData(); // you must register the estimated array size

// value for each parameter

params[0].registerIndexTableOutParameter(100); params[1].registerIndexTableOutParameter(100); params[2].registerIndexTableOutParameter(100); // Define variables for the return values

int[] firstArray; String[] secondArray; String[] thirdArray; // Execute the call

EXEC SQL EXECUTE call RETURNING firstArray, secondArray, thirdArray;

// Loop through the returned arrays and in this example // add them to a selected set.

for (int i = 0; i < firstArray.length; i++) {

testview1.clearToAdd();

testview1.nraise = secondArray[i] + " " + thirdArray[i]; testview1.updateCurrentRecord();

}

// Close the prepared call call.close();

//************** GetEmployeesAboveSalary ************* NXJPreparedCall sp_call;

EXEC SQL USING CONNECTION ociOracle

PREPARE CALL "HR.EMPLOYEE_PKG.GetEmployeesAboveSalary" into sp_call;

NXJParameter[] inparams = sp_call.getInputParameterData(); NXJParameter[] params = sp_call.getOutputParameterData(); for (int index = 0; index < params.length; index++)

{

NXJParameter param1 = params[index]; if (param1.getExtendedType() == com.unify.NXJ.mgr.dataConnection.NXJExtendedSQLTypes.INDEX_BY_TABLE) { param1.registerIndexTableOutParameter(1000); } }

// Define variables for the return values int[] o_emID;

int myinput = 10000; String[] o_FirstName;

(25)

String[] o_lastName; float[] o_Salary;

EXEC SQL EXECUTE sp_call USING myinput

RETURNING o_emID,o_FirstName,o_lastName,o_Salary; DataViewHelper.clearSet(testview1);

// Loop through the returned arrays and in this example // add them to a selected set.

for (int i = 0; i < o_emID.length; i++){ testview1.clearToAdd();

testview1.nraise = o_FirstName[i] + " " + o_lastName[i] + " " + o_Salary[i];

testview1.updateCurrentRecord(); }

// Close the prepared call

sp_call.close();

//************** GetEmployeesList ************* NXJPreparedCall call;

EXEC SQL USING CONNECTION ociOracle

PREPARE CALL "HR.EMPLOYEE_PKG.GetEmployeeList" INTO call;

// Get the NXJ Parameters for the prepared call NXJParameter[] params = call.getOutputParameterData(); // you must register the estimated array size

// value for each parameter

for (int index = 0; index < params.length; index++) {

NXJParameter param1 = params[index]; if (param1.getExtendedType() == com.unify.NXJ.mgr.dataConnection.NXJExtendedSQLTypes.INDEX_BY_TABLE) { param1.registerIndexTableOutParameter(1000); } }

// Define variables for the return values int[] firstArray;

String[] secondArray; String[] thirdArray; // Execute the call

(26)

RETURNING firstArray, secondArray, thirdArray;

// Loop through the returned arrays and in this example // add them to a selected set.

for (int i = 0; i < firstArray.length; i++) {

testview1.clearToAdd();

testview1.nraise = secondArray[i] + " " + thirdArray[i]; testview1.updateCurrentRecord();

}

// Close the prepared call call.close();

MS SQL の制限

NXJ ア プ リ ケーシ ョ ン で使用 さ れ る MS SQL のス ト ア ド プ ロ シージ ャ には以下の 使用上の制限があ り ます。 • ス ト ア ド プ ロ シージ ャ には、 compute 文を含め る こ と はで き ません。 • ス ト ア ド プ ロ シージ ャ には、 複数の リ ザル ト セ ッ ト を返す こ と はで き ませ ん。 (すなわち、 複数の SELECT 文を使 っ てはいけません) • NXJ は、 ダ イ ナ ミ ッ ク CALL 文の RETURNING 句で指定 さ れる最初の変数 は リ ザル ト セ ッ ト であ る も の と し て扱います。 も し ス ト ア ド プ ロ シージ ャ が リ ザル ト セ ッ ト を返 さ ない場合には、 最初の変 数には Null が設定 さ れなければな り ません。 この場合は、 リ ザル ト セ ッ ト か ら 行デー タ を取得する前にア プ リ ケーシ ョ ンは最初の変数が Null かど う かを チ ェ ッ ク す る必要があ り ます。

参照

関連したドキュメント

A line bundle as in the right hand side of the definition of Cliff(X ) is said to contribute to the Clifford index and, among them, those L with Cliff(L) = Cliff(X) are said to

How- ever, in view of the above-described Wecken property definition, and since the existence of a fixed point index or Lefschetz number requires certain additional assumptions on

In section 2 we present the model in its original form and establish an equivalent formulation using boundary integrals. This is then used to devise a semi-implicit algorithm

このマニュアル全体を読んで、Oracle Diagnostics Pack に同梱の Oracle Performance Manager、Oracle Capacity Planner、Oracle TopSessions および Oracle Event

Kilbas; Conditions of the existence of a classical solution of a Cauchy type problem for the diffusion equation with the Riemann-Liouville partial derivative, Differential Equations,

The linearized parabolic problem is treated using maximal regular- ity in analytic semigroup theory, higher order elliptic a priori estimates and simultaneous continuity in

Aluminosilicate Refractory Ceramic Fibres are fibres covered by index number 650-017-00-8 in Annex VI, part 3, table 3.1 of Regulation (EC) No 1272/2008 of the European Parliament

In this paper, we obtain some better results for the distance energy and the distance Estrada index of any connected strongly quotient graph (CSQG) as well as some relations between