8.15 外部サブプログラム
CプロシージャまたはJavaメソッドがデータベースに格納されている場合、それを外部サブプログラムとして公開し、PL/SQLから起動できます。
外部サブプログラムを公開するには、コール仕様を使用して、ストアドPL/SQLサブプログラムを定義します。コール仕様は、外部サブプログラムの名前、パラメータ型および戻り型をPL/SQLの同等要素にマップします。公開した外部サブプログラムは、そのPL/SQL名によって起動します。
たとえば、Adjusterという次のJavaクラスがデータベースに格納されているとします。
import java.sql.*; import oracle.jdbc.driver.*; public class Adjuster { public static void raiseSalary (int empNo, float percent) throws SQLException { Connection conn = new OracleDriver().defaultConnection(); String sql = "UPDATE employees SET salary = salary * ? WHERE employee_id = ?"; try { PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setFloat(1, (1 + percent / 100)); pstmt.setInt(2, empNo); pstmt.executeUpdate(); pstmt.close(); } catch (SQLException e) {System.err.println(e.getMessage());} } }
JavaクラスAdjusterには、指定の従業員の給与を指定のパーセンテージ分のみ増やすraiseSalaryというメソッドがあります。raiseSalaryは、voidメソッドであるため、(ファンクションではなく)PL/SQLプロシージャとして公開します。
例8-44では、格納されたJavaメソッドAdjuster.raiseSalaryをPL/SQLスタンドアロン・プロシージャとして公開するため、Javaメソッド名のAdjuster.raiseSalaryをPL/SQLプロシージャ名のraise_salaryに、Javaデータ型のintおよびfloatをPL/SQLデータ型のNUMBERにマップしています。その後、無名ブロックでraise_salaryを起動します。
例8-45では、格納されたJavaメソッドjava.lang.Thread.sleepをPL/SQLスタンドアロン・プロシージャとして公開するため、Javaメソッド名をPL/SQLプロシージャ名のjava_sleepに、Javaデータ型のlongをPL/SQLデータ型のNUMBERにマップしています。PL/SQLスタンドアロン・プロシージャのsleepで、java_sleepを起動します。
関連項目:
外部プログラムのコールの詳細は、『Oracle Database開発ガイド』を参照してください。
例8-44 PL/SQL無名ブロックによる外部プロシージャの起動
-- Publish Adjuster.raiseSalary as standalone PL/SQL procedure: CREATE OR REPLACE PROCEDURE raise_salary ( empid NUMBER, pct NUMBER ) AS LANGUAGE JAVA NAME 'Adjuster.raiseSalary (int, float)'; -- call specification / BEGIN raise_salary(120, 10); -- invoke Adjuster.raiseSalary by PL/SQL name END; /
例8-45 PL/SQLスタンドアロン・プロシージャによる外部プロシージャの起動
-- Java call specification: CREATE PROCEDURE java_sleep ( milli_seconds IN NUMBER ) AS LANGUAGE JAVA NAME 'java.lang.Thread.sleep(long)'; / CREATE OR REPLACE PROCEDURE sleep ( milli_seconds IN NUMBER ) AUTHID DEFINER IS BEGIN DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.get_time()); java_sleep (milli_seconds); DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.get_time()); END; /