ストアド・プロシージャのコール

特定のアプリケーション・データベース表に対する選択、挿入、更新、削除およびロックの動作をカプセル化した既存のPL/SQLパッケージがある場合は、次のコード・サンプルに示すように、ビルトインのエンティティ・オブジェクト・フレームワーク・メソッドdoDML()およびdoSelect()をオーバーライドして、エンティティ・オブジェクトのデータベース永続操作が、完全に既存パッケージに基づいて行われるようにできます。エンティティ・オブジェクト・エディタでdoDML()メソッドのスケルトン・コードを生成できることに注意してください。

このトピックでは、最初にストアド・プロシージャとエンティティ・オブジェクトのコードを示し、その後で説明します。

SQLストアド・プロシージャ

CREATE OR REPLACE PACKAGE departments_pkg IS

  PROCEDURE do_lock(p_deptno number, p_dname out varchar2, p_loc out number);
  PROCEDURE do_select(p_deptno number, p_dname out varchar2, p_loc out number);
  PROCEDURE do_update(p_deptno number, p_dname varchar2, p_loc number);
  PROCEDURE do_insert(p_deptno number, p_dname varchar2, p_loc number);
  PROCEDURE do_delete(p_deptno number);

END;
.
/
SHOW ERRORS

CREATE OR REPLACE PACKAGE BODY departments_pkg IS
  PROCEDURE do_select(p_deptno number, p_dname out varchar2, p_loc out number) IS
  BEGIN
    SELECT department_name, location_id
      INTO p_dname, p_loc
      FROM departments
     WHERE department_id = p_deptno
    FOR UPDATE NOWAIT;
  END;

  PROCEDURE do_lock(p_deptno number, p_dname out varchar2, p_loc out number) IS
  BEGIN
    SELECT department_name, location_id
      INTO p_dname, p_loc
      FROM departments
     WHERE department_id = p_deptno;
  END;

  PROCEDURE do_update(p_deptno number, p_dname varchar2, p_loc number)  IS
  BEGIN
    UPDATE departments
       SET department_name = p_dname, location_id = p_loc
      WHERE department_id = p_deptno;
  END;

  PROCEDURE do_insert(p_deptno number, p_dname varchar2, p_loc number) IS
  BEGIN
    INSERT INTO departments(department_id, department_name,location_id)
    VALUES (p_deptno,p_dname,p_loc);
  END;

  PROCEDURE do_delete(p_deptno number) IS
  BEGIN
    DELETE FROM departments
     WHERE department_id = p_deptno;
  END;

END;
.
/
SHOW ERRORS

    

エンティティ・オブジェクト・コード

protected void doSelect(boolean lock) {
  if (lock) {
    this.handleStoredProcLock();
  }
  else {
    this.handleStoredProcSelect();
  }
}
public void doDML(int operation, TransactionEvent e) {
  switch (operation) {
    case DML_INSERT: {
      handleStoredProcInsert();
      break;
    }
    case DML_UPDATE: {
      handleStoredProcUpdate();
      break;
    }
    case DML_DELETE: {
      handleStoredProcDelete();
      break;
    }
  }
}

void handleStoredProcSelect() {
  CallableStatement st = null;
  try {
    String stmt = "BEGIN departments_pkg.do_select(?,?,?); END;";
    DBTransaction tr = getDBTransaction();
    st = tr.createCallableStatement(stmt,1);
    st.setLong(1,getDepartmentId().longValue());
    st.registerOutParameter(2,Types.VARCHAR);
    st.registerOutParameter(3,Types.NUMERIC);
    int rows = st.executeUpdate();
    populateAttribute(DEPARTMENTNAME,st.getString(2),true,false);
    populateAttribute(LOCATIONID,st.getBigDecimal(3),true,false);
  }
  catch (SQLException s) {
    throw new JboException(s);
  }
  finally {
    try {
      if (st != null) st.close();
    }
    catch (SQLException s) { /* ignore */}
  }
}

void handleStoredProcDelete() {
  CallableStatement st = null;
  try {
    String stmt = "BEGIN departments_pkg.do_delete(?); END;";
    DBTransaction tr = getDBTransaction();
    st = tr.createCallableStatement(stmt,1);
    st.setLong(1,getDepartmentId().longValue());
    int rows = st.executeUpdate();
  }
  catch (SQLException s) {
    throw new JboException(s);
  }
  finally {
    try {
      if (st != null) st.close();
    }
    catch (SQLException s) { /* ignore */}
  }
}

void handleStoredProcInsert() {
  CallableStatement st = null;
  try {
    String stmt = "BEGIN departments_pkg.do_insert(?,?,?); END;";
    DBTransaction tr = getDBTransaction();
    st = tr.createCallableStatement(stmt,1);
    st.setLong(1,getDepartmentId().longValue());
    if (getDepartmentName() != null) {
      st.setString(2,getDepartmentName());
    }
    else {
      st.setNull(2,Types.VARCHAR);
    }
    if (getLocationId() != null) {
      st.setLong(3,getLocationId().longValue());
    }
    else {
      st.setNull(3,Types.VARCHAR);
    }
    int rows = st.executeUpdate();
  }
  catch (SQLException s) {
    throw new JboException(s);
  }
  finally {
    try {
      if (st != null) st.close();
    }
    catch (SQLException s) { /* ignore */}
  }
}

void handleStoredProcUpdate() {
  CallableStatement st = null;
  try {
    String stmt = "BEGIN departments_pkg.do_update(?,?,?); END;";
    DBTransaction tr = getDBTransaction();
    st = tr.createCallableStatement(stmt,1);
    st.setLong(1,getDepartmentId().longValue());
    if (getDepartmentName() != null) {
      st.setString(2,getDepartmentName());
    }
    else {
      st.setNull(2,Types.VARCHAR);
    }
    if (getLocationId() != null) {
      st.setLong(3,getLocationId().longValue());
    }
    else {
      st.setNull(3,Types.VARCHAR);
    }
    int rows = st.executeUpdate();
  }
  catch (SQLException s) {
    throw new JboException(s);
  }
  finally {
    try {
      if (st != null) st.close();
    }
    catch (SQLException s) { /* ignore */}
  }
}

void handleStoredProcLock() {
  CallableStatement st = null;
  try {
    String stmt = "BEGIN departments_pkg.do_lock(?,?,?); END;";
    DBTransaction tr = getDBTransaction();
    st = tr.createCallableStatement(stmt,1);
    st.setLong(1,getDepartmentId().longValue());
    st.registerOutParameter(2,Types.VARCHAR);
    st.registerOutParameter(3,Types.NUMERIC);
    int rows = st.executeUpdate();
    String newDname     = st.getString(2);
    BigDecimal newLoc   = st.getBigDecimal(3);
    // Compare the old values to the current values to
    // detect if row has changed.
    compareOldAttrTo(DEPARTMENTNAME,newDname);
    compareOldAttrTo(LOCATIONID,newLoc);
  }
  catch (SQLException s) {
    throw new JboException(s);
  }
  finally {
    try {
      if (st != null) st.close();
    }
    catch (SQLException s) { /* ignore */}
  }
}

void compareOldAttrTo(int slot, Object newVal) {
    if ((getPostedAttribute(slot) == null && newVal != null) ||
        (getPostedAttribute(slot) != null && newVal == null) ||
        (getPostedAttribute(slot) != null && newVal != null &&
         !getPostedAttribute(slot).equals(newVal))) {
      throw new RowInconsistentException(createPrimaryKey(getDepartmentId()));
    }
}

    

機能

doSelect()のコードは、オーバーライドされたヘルパー・メソッドをコールします。ヘルパー・メソッドは、フレームワークで主キーに基づく行をフォルトインする(doSelect(false))か、既存の行をロックする(doSelect(true))かによって異なります。

doDML()のコードは、実行を要求された操作の値に応じて、適切なヘルパー・メソッドをコールします。

各ヘルパー・メソッドはDBTransactionインタフェースのcreateCallableStatement()メソッドを使用して、JDBCコール可能な文を作成し、そのパラメータをバインドして実行します。

ロックのヘルパー・メソッドはロックを取得した後でDname属性とLoc属性を調べて、現在のユーザーが行を選択してから変更しようとするまでの間に、別のトランザクションによって行が変更されていないことを確認します。

現在、DBAはDepartment表の挿入、更新および削除権限を完全に取り消すことができます。また、すべてのDML操作は、作成、変更または削除されるDeptエンティティのストアド・プロシージャにルーティングされます。


関連項目
ストアド・プロシージャの使用について

 

Copyright © 1997, 2004, Oracle. All rights reserved.