ストアドプロシージャの実行

ストアドプロシージャは、EnterpriseDBのSPLで記述され、データベースに格納されるモジュールです。ストアドプロシージャは、プロシージャにデータを提供する入力パラメータと、プロシージャからデータを返す出力パラメータを定義できます。ストアドプロシージャはサーバー内で実行され、データベースアクセスコマンド(SQL)、制御ステートメント、およびデータベースから取得したデータを操作するデータ構造で構成されます。

ストアドプロシージャは、クライアントからのデータを保存する前に広範なデータ操作が必要な場合に特に役立ちます。ストアドプロシージャを使用してバッチプログラムでデータを操作することも効率的です。

ストアドプロシージャの呼び出し¶

CallableStatementクラスは、Javaプログラムがストアドプロシージャを呼び出す方法を提供します。 CallableStatementオブジェクトには、入力( INパラメーター)、出力( OUTパラメーター)、またはその両方( IN OUTパラメーター)に使用されるパラメーターの可変数をCallableStatementことができます。

JDBCでストアドプロシージャを呼び出すための構文を以下に示します。角括弧はオプションのパラメータを示していることに注意してください。それらはコマンド構文の一部ではありません。

{call procedure_name([?, ?, ...])}

結果パラメーターを返すプロシージャーを呼び出す構文は次のとおりです。

{? = call procedure_name([?, ?, ...])}

各疑問符は、パラメーターのプレースホルダーとして機能します。ストアドプロシージャは、プレースホルダーがIN 、 OUT 、またはIN OUTパラメーターを表し、Javaコードが一致する必要があるかどうかを決定します。 IN (またはIN OUT )パラメーターの値を指定する方法、およびOUT (またはIN OUT )パラメーターで返された値をすぐに取得する方法を示します。

単純なストアドプロシージャの実行

リスト1.7-aは、各従業員の給与を10%増やすストアドプロシージャを示しています。 increaseSalary 、発信者からの引数を期待していないし、任意の情報を返しません。

リスト1.7-a

 CREATE OR REPLACE PROCEDURE increaseSalary
IS
  BEGIN
    UPDATE emp SET sal = sal * 1 . 10 ;
  END ;

リスト1.7-bは、 increaseSalaryプロシージャを呼び出す方法を示しています。

リスト1.7-b

public void SimpleCallSample(Connection con)
{
  try
  {
    CallableStatement stmt = con.prepareCall("{call increaseSalary()}");
    stmt.execute();
    System.out.println("Stored Procedure executed successfully");
  }
  catch(Exception err)
  {
    System.out.println("An error has occurred.");
    System.out.println("See full details below.");
    err.printStackTrace();
  }
}

Javaアプリケーションからストアドプロシージャを呼び出すには、 CallableStatementオブジェクトを使用します。 CallableStatementクラスをから派生しStatementのように、クラスおよびStatementクラス、あなたが取得するCallableStatement尋ねることによってオブジェクトをConnectionあなたのための1つを作成するためにオブジェクトを。 ConnectionからCallableStatementを作成するには、 prepareCall()メソッドを使用します。

CallableStatement stmt = con.prepareCall("{call increaseSalary()}");

名前が示すとおり、 prepareCall()メソッドはステートメントを準備しますが、実行はしません。次の例でわかるように、アプリケーションは通常、 prepareCall()の呼び出しとexecute()呼び出しの間でパラメーター値をバインドします。サーバーでストアドプロシージャを呼び出すには、 execute()メソッドを呼び出します。

stmt.execute();

このストアドプロシージャ( increaseSalary )はINパラメーターを予期せず、呼び出し元に情報を返さなかった( OUTパラメーターを使用)ため、プロシージャの呼び出しはCallableStatementオブジェクトを作成し、そのオブジェクトのexecute()メソッドを呼び出すだけです

次のセクションでは、呼び出し元からのデータ( INパラメーター)を必要とするストアドプロシージャを呼び出す方法を示します。

INパラメータを使用したストアドプロシージャの実行

次の例のコードは、まずempInsertという名前のストアドプロシージャを作成してから呼び出します。 empInsertは、従業員情報を含むINパラメーターが必要です: empno 、 ename 、 job 、 sal 、 comm 、 deptno 、およびmgr 。 empInsert 、その情報をempテーブルに挿入します。

リスト1.8-aは、Advanced Serverデータベースにストアドプロシージャを作成します。

リスト1.8-a

 CREATE OR REPLACE PROCEDURE empInsert (
    pEname  IN VARCHAR ,
    pJob    IN VARCHAR ,
    pSal    IN FLOAT4 ,
    pComm   IN FLOAT4 ,
pDeptno IN INTEGER ,
pMgr    IN INTEGER
)
AS
DECLARE
  CURSOR getMax IS SELECT MAX ( empno ) FROM emp ;
  max_empno INTEGER : = 10 ;
BEGIN
  OPEN getMax ;
  FETCH getMax INTO max_empno ;
  INSERT INTO emp ( empno , ename , job , sal , comm , deptno , mgr )
    VALUES ( max_empno + 1 , pEname , pJob , pSal , pComm , pDeptno , pMgr );
  CLOSE getMax ;
END ;

リスト1.8-bは、Javaからストアドプロシージャを呼び出す方法を示しています。

リスト1.8-b

public void CallExample2(Connection con)
{
  try
  {
    Console c = System.console();
    String commandText = "{call empInsert(?,?,?,?,?,?)}";
    CallableStatement stmt = con.prepareCall(commandText);
    stmt.setObject(1, new String(c.readLine("Employee Name :")));
    stmt.setObject(2, new String(c.readLine("Job :")));
    stmt.setObject(3, new Float(c.readLine("Salary :")));
    stmt.setObject(4, new Float(c.readLine("Commission :")));
    stmt.setObject(5, new Integer(c.readLine("Department No :")));
    stmt.setObject(6, new Integer(c.readLine("Manager")));
    stmt.execute();
  }
  catch(Exception err)
  {
    System.out.println("An error has occurred.");
    System.out.println("See full details below.");
    err.printStackTrace();
  }
}

コマンド( commandText )の各プレースホルダー(?)は、後でデータに置き換えられるコマンド内のポイントを表します。

String commandText = "{call EMP_INSERT(?,?,?,?,?,?)}";
CallableStatement stmt = con.prepareCall(commandText);

setObject()メソッドは、値をINまたはIN OUTプレースホルダーにバインドします。 setObject()呼び出すたびに、パラメーター番号とそのパラメーターにバインドする値を指定します。

stmt.setObject(1, new String(c.readLine("Employee Name :")));
stmt.setObject(2, new String(c.readLine("Job :")));
stmt.setObject(3, new Float(c.readLine("Salary :")));
stmt.setObject(4, new Float(c.readLine("Commission :")));
stmt.setObject(5, new Integer(c.readLine("Department No :")));
stmt.setObject(6, new Integer(c.readLine("Manager")));

各プレースホルダーに値を指定すると、このメソッドはexecute()メソッドを呼び出してステートメントをexecute()ます。

OUTパラメータを使用したストアドプロシージャの実行

次の例では、 deptSelectというSPLストアドプロシージャを作成して呼び出します。この手順では、1つのINパラメーター(部門番号)が必要であり、部門番号に対応する2つのOUTパラメーター(部門名と場所)を返します。リスト1.9-aのコードは、 deptSelectプロシージャを作成します。

リスト1.9-a

 CREATE OR REPLACE PROCEDURE deptSelect
(
  p_deptno IN  INTEGER ,
  p_dname  OUT VARCHAR ,
  p_loc    OUT VARCHAR
)
AS
DECLARE
  CURSOR deptCursor IS SELECT dname , loc FROM dept WHERE deptno = p_deptno ;
BEGIN
  OPEN deptCursor ;
  FETCH deptCursor INTO p_dname , p_loc ;

  CLOSE deptCursor ;
END ;

リスト1.9-bは、 deptSelectストアドプロシージャを呼び出すために必要なJavaコードを示しています。

リスト1.9-b

public void GetDeptInfo(Connection con)
{
  try
  {
    Console c = System.console();
    String commandText = "{call deptSelect(?,?,?)}";
    CallableStatement stmt = con.prepareCall(commandText);
stmt.setObject(1、new Integer(c.readLine( "Dept No:"))); stmt.registerOutParameter(2、Types.VARCHAR); stmt.registerOutParameter(3、Types.VARCHAR); stmt.execute(); System.out.println( "部門名:" + stmt.getString(2)); System.out.println( "Location:" + stmt.getString(3)); } catch(Exception err){System.out.println( "エラーが発生しました。"); System.out.println( "以下の詳細を参照してください。"); err.printStackTrace(); }} 

コマンド( commandText )の各プレースホルダー(?)は、後でデータに置き換えられるコマンド内のポイントを表します。

String commandText = "{call deptSelect(?,?,?)}";
CallableStatement stmt = con.prepareCall(commandText);

setObject()メソッドは、値をIN or ``IN OUTプレースホルダーにバインドします。 setObject()を呼び出すときは、プレースホルダーを(序数で)特定し、そのプレースホルダーの代わりに置換する値を提供する必要があります。

stmt.setObject(1, new Integer(c.readLine("Dept No :")));

CallableStatementオブジェクトを実行する前に、各OUTパラメーターのJDBCタイプを登録する必要があります。 JDBCタイプの登録は、 registerOutParameter()メソッドを使用して行われます。

stmt.registerOutParameter(2, Types.VARCHAR);
stmt.registerOutParameter(3, Types.VARCHAR);

ステートメントの実行後、 CallableStatement's getterメソッドはOUTパラメーター値を取得しますVARCHAR値を取得するには、 getString() getterメソッドを使用します。

stmt.execute();
System.out.println("Dept Name: " + stmt.getString(2));
System.out.println("Location : " + stmt.getString(3));

現在の例では、 GetDeptInfo() 2つのOUTパラメーターを登録し、(ストアドプロシージャの実行後) OUTパラメーターで返された値を取得します。両方のOUTパラメーターはVARCHAR値として定義されているため、 GetDeptInfo()はgetString()メソッドを使用してOUTパラメーターを取得します。

IN OUTパラメーターを使用したストアドプロシージャの実行

次の例のコードは、1つのINパラメーター( p_deptno )、2つのIN OUTパラメーター( p_empnoおよびp_ename )、および3つのOUTパラメーター( p_job 、 p_hiredateおよびp_sal )で定義されたempQueryという名前のストアドプロシージャを作成して呼び出します。 empQueryは、2つのIN OUTパラメーターと3つのOUTパラメーターで従業員に関する情報を返します。

リスト1.10-aは、 empQueryという名前のストアドプロシージャを作成します。

リスト1.10-a

 CREATE OR REPLACE PROCEDURE empQuery
(
    p_deptno        IN     NUMBER ,
    p_empno         IN OUT NUMBER ,
    p_ename         IN OUT VARCHAR2 ,
    p_job           OUT    VARCHAR2 ,
    p_hiredate      OUT    DATE ,
    p_sal           OUT    NUMBER
)
IS
BEGIN
  SELECT empno , ename , job , hiredate , sal
    INTO p_empno , p_ename , p_job , p_hiredate , p_sal
    FROM emp
    WHERE deptno = p_deptno
      AND ( empno = p_empno
      OR ename = UPPER ( p_ename ));
END ;

1.10-Bをリスト呼び出す実証empQuery 、手続きをするために値を提供するINパラメーター、および取り扱いOUTとIN OUTパラメータを:

リスト1.10-b

public void CallSample4(Connection con)
{
  try
  {
    Console c = System.console();
    String commandText = "{call emp_query(?,?,?,?,?,?)}";
    CallableStatement stmt = con.prepareCall(commandText);
    stmt.setInt(1, new Integer(c.readLine("Department No:")));
    stmt.setInt(2, new Integer(c.readLine("Employee No:")));
    stmt.setString(3, new String(c.readLine("Employee Name:")));
    stmt.registerOutParameter(2, Types.INTEGER);
    stmt.registerOutParameter(3, Types.VARCHAR);
    stmt.registerOutParameter(4, Types.VARCHAR);
    stmt.registerOutParameter(5, Types.TIMESTAMP);
    stmt.registerOutParameter(6, Types.NUMERIC);
    stmt.execute();
    System.out.println("Employee No: " + stmt.getInt(2));
    System.out.println("Employee Name: " + stmt.getString(3));
    System.out.println("Job : " + stmt.getString(4));
    System.out.println("Hiredate : " + stmt.getTimestamp(5));
System.out.println( "Salary:" + stmt.getBigDecimal(6)); } catch(Exception err){System.out.println( "エラーが発生しました。"); System.out.println( "以下の詳細を参照してください。"); err.printStackTrace(); }} 

コマンド( commandText )の各プレースホルダー(?)は、後でデータに置き換えられるコマンド内のポイントを表します。

String commandText = "{call emp_query(?,?,?,?,?,?)}";
CallableStatement stmt = con.prepareCall(commandText);

setInt()メソッドは、 Integer値をINまたはIN OUTプレースホルダーにバインドする型固有のsetterメソッドです。 setInt()の呼び出しは、パラメーター番号を指定し、そのプレースホルダーの代わりに置き換える値を提供します。

stmt.setInt(1, new Integer(c.readLine("Department No:")));
stmt.setInt(2, new Integer(c.readLine("Employee No:")));

setString()メソッドは、 String値をINまたはIN OUTプレースホルダーにバインドします。

stmt.setString(3, new String(c.readLine("Employee Name:")));

CallableStatement実行する前に、 registerOutParameter()メソッドを呼び出して、各OUTパラメーターのJDBCタイプを登録する必要があります。

stmt.registerOutParameter(2, Types.INTEGER);
stmt.registerOutParameter(3, Types.VARCHAR);
stmt.registerOutParameter(4, Types.VARCHAR);
stmt.registerOutParameter(5, Types.TIMESTAMP);
stmt.registerOutParameter(6, Types.NUMERIC);

INパラメーターを使用してプロシージャーを呼び出す前に、setterメソッドを使用してそのパラメーターに値を割り当てる必要があることに注意してください。 OUTパラメーターを使用してプロシージャーを呼び出す前に、そのパラメーターのタイプを登録します。次に、getterメソッドを呼び出して返された値を取得できます。定義する手順を呼び出すときはIN OUTパラメータを、あなたはすべての3つのアクションを実行する必要があります。

  • パラメーターに値を割り当てます。
  • パラメーターのタイプを登録します。
  • getterメソッドで返された値を取得します。