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

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

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

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

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

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

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

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

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

Each question mark serves as a placeholder for a parameter. The stored procedure determines if the placeholders represent IN, OUT, or IN OUT parameters and the Java code must match. We will show you how to supply values for IN (or IN OUT) parameters and how to retrieve values returned in OUT (or IN OUT) parameters in a moment.

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

リスト1.7-aは、各従業員の給与を 10% 増やすストアドプロシージャを示しています。 increaseSalary は呼び出し元からの引数を期待せず、情報を返しません:

CREATE OR REPLACE PROCEDURE increaseSalary
IS
  BEGIN
    UPDATE emp SET sal = sal * 1.10;
  END;

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

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 クラスと同様に、 Connection オブジェクトに1つ作成してもらうことで CallableStatement オブジェクトを取得しますあなた。 Connection から CallableStatement を作成するには、 prepareCall() メソッドを使用します:

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

As the name implies, the prepareCall() method prepares the statement, but does not execute it. As you will see in the next example, an application typically binds parameter values between the call to prepareCall() and the call to execute(). To invoke the stored procedure on the server, call the execute() method.

stmt.execute();

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

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

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

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

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

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からストアドプロシージャを呼び出す方法を示しています。

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);

The setObject() method binds a value to an IN or IN OUT placeholder. Each call to setObject() specifies a parameter number and a value to bind to that parameter:

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() メソッドを呼び出してステートメントを実行します。

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

The next example creates and invokes an SPL stored procedure called deptSelect. This procedure requires one IN parameter (department number) and returns two OUT parameters (the department name and location) corresponding to the department number. The code in Listing 1.9-a creates the deptSelect procedure:

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コードを示しています。

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("Dept Name: " + stmt.getString(2));
    System.out.println("Location : " + stmt.getString(3));
  }
  catch(Exception err)
  {
    System.out.println("An error has occurred.");
    System.out.println("See full details below.");
    err.printStackTrace();
  }
}

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

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

The setObject() method binds a value to an IN or ``IN OUT placeholder. When calling setObject() you must identify a placeholder (by its ordinal number) and provide a value to substitute in place of that placeholder:

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

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

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

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

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

In the current example GetDeptInfo() registers two OUT parameters and (after executing the stored procedure) retrieves the values returned in the OUT parameters. Since both OUT parameters are defined as VARCHAR values, GetDeptInfo() uses the getString() method to retrieve the OUT parameters.

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

The code in the next example creates and invokes a stored procedure named empQuery defined with one IN parameter (p_deptno), two IN OUT parameters (p_empno and p_ename) and three OUT parameters (p_job, p_hiredate and p_sal). empQuery then returns information about the employee in the two IN OUT parameters and three OUT parameters.

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

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 パラメーターの処理を示しています。

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("An error has occurred.");
    System.out.println("See full details below.");
    err.printStackTrace();
  }
}

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

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

The setInt() method is a type-specific setter method that binds an Integer value to an IN or IN OUT placeholder. The call to setInt() specifies a parameter number and provides a value to substitute in place of that placeholder:

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メソッドで返された値を取得します。