9.3.2 HiRDBが提供する外部Javaストアドルーチンのサンプル
(1) サンプル1
指定した年月のカレンダーを取得するJavaストアドプロシジャの例です。
-
外部Java手続き本体(ファイル名:sample1.java)
/* ALL RIGHTS RESERVED,COPYRIGHT (C)2000,HITACHI,LTD. */ /* LICENSED MATERIAL OF HITACHI,LTD. */ /************************************************************************/ /* name = HiRDB 06-00 Javaストアドプロシジャ サンプルプログラム 1 */ /************************************************************************/ import java.lang.*; import java.util.*; /************************************************************************/ /* name = サンプル1 クラス */ /************************************************************************/ public class sample1 { /*==================================================================*/ /* name = デバッグ用メインメソッド */ /*==================================================================*/ public static void main(java.lang.String[] args) { java.lang.Integer year = new Integer(args[0]); java.lang.Integer month = new Integer(args[1]); java.lang.String calendar[] = new String[1]; calendar(year, month, calendar); System.out.println(calendar[0]); } /*====================================================================*/ /* name = サンプル1 メソッド */ /*====================================================================*/ public static void calendar(java.lang.Integer year, java.lang.Integer month, java.lang.String[] calendar) { int DayOfWeek; // 指定月の1日の曜日 int week; // 改行制御用 int wyear = year.intValue(); // 年ワーク int wmonth = month.intValue(); // 月ワーク // カレンダーヘッダ作成 calendar[0] = " " + wyear + " / " + wmonth + "\n"; calendar[0] += "Sun Mon Thu Wed Tue Fri Sat\n"; // カレンダーオブジェクト生成 Calendar target_cal = new GregorianCalendar(wyear, wmonth - 1, 1); // 指定月の1日の曜日算出 DayOfWeek = target_cal.get(Calendar.DAY_OF_WEEK); // 開始曜日まで空白設定 for (week = 1; week < DayOfWeek; week++) { calendar[0] += " "; } // 日付設定 for (; target_cal.get(Calendar.MONTH) == wmonth - 1; target_cal.add(Calendar.DATE, 1), week++) { // 日付設定と桁数に応じたスペース調整 if (target_cal.get(Calendar.DATE) < 10) { calendar[0] += " " + target_cal.get(Calendar.DATE); } else { calendar[0] += " " + target_cal.get(Calendar.DATE); } // 日付間のパディング文字の設定 if (week == 7) { calendar[0] += "\n"; week = 0; } else { calendar[0] += " "; } } return; } }
上記の外部Java手続き本体を使用して,Javaストアドプロシジャを定義,実行する例を次に示します。
-
Javaファイルのコンパイル(HP-UXの場合の例です)
javac sample1.java
-
JARファイルの作成(HP-UXの場合の例です)
jar -cvf sample1.jar sample1.class
-
HiRDBへのJARファイルの登録(SQLのINSTALL JARを使用した例です)
INSTALL JAR 'sample1.jar' ;
-
Javaストアドプロシジャの定義
CREATE PROCEDURE calendar(IN pyear INT, IN pmonth INT, OUT calendar VARCHAR(255)) LANGUAGE JAVA EXTERNAL NAME 'sample1.jar:sample1.calendar(java.lang.Integer, java.lang.Integer, java.lang.String[]) returns void' PARAMETER STYLE JAVA end_proc;
-
Javaストアドプロシジャの実行
CALL calendar(?,?,?)
(2) サンプル2
処理する範囲を年月日で指定し,その範囲のgoods_no列に対応した合計数を更新する例です。
なお,表は次のように定義されているものとします。
CREATE TABLE master_t1 (goods_no int,total_quantity dec(17,2)) CREATE TABLE tran_t1(goods_no int,quantity_1 dec(17,2),entrydate date)
-
外部Java手続き本体(ファイル名:sample2.java)
/* ALL RIGHTS RESERVED,COPYRIGHT (C)2000,HITACHI,LTD. */ /* LICENSED MATERIAL OF HITACHI,LTD. */ /************************************************************************/ /* name = HiRDB 06-00 Javaストアド サンプル2 */ /************************************************************************/ import java.lang.*; import java.math.*; import java.sql.*; /************************************************************************/ /* name = サンプル2クラス */ /************************************************************************/ public class sample2 { /*==================================================================*/ /* name = デバッグ用メインメソッド */ /*==================================================================*/ public static void main(String args[]) throws SQLException { java.sql.Date fromdate = Date.valueOf("1996-06-01"); java.sql.Date todate = Date.valueOf("1996-06-30"); try { // Driverクラスの登録 Class.forName("JP.co.Hitachi.soft.HiRDB.JDBC.HiRDBDriver"); } catch (ClassNotFoundException ex) { System.out.println("\n*** ClassNotFoundException caught ***\n"); ex.printStackTrace(); System.out.println (""); System.out.println("\n*************************************\n"); return; } jproc1(fromdate, todate); } /*==================================================================*/ /* name = サンプル2メソッド */ /*==================================================================*/ public static void jproc1(java.sql.Date fromdate, java.sql.Date todate) throws SQLException { java.lang.Integer x_goods_no; java.math.BigDecimal x_quantity_1, x_total_quantity; try { // コネクトオブジェクト生成(Java手続き内ではCONNECTは発行されない) java.sql.Connection con = DriverManager.getConnection("jdbc:hitachi:hirdb"); con.setAutoCommit(false); // 自動コミットの抑止 // SELECT(stmt1)前処理 java.sql.PreparedStatement stmt1 = con.prepareStatement("SELECT goods_no, quantity_1, entrydate FROM tran_t1 WHERE entrydate BETWEEN ? AND ? ORDER BY entrydate"); // SELECT(stmt2)前処理(ループの外で前処理しておく) java.sql.PreparedStatement stmt2 = con.prepareStatement("SELECT total_quantity FROM master_t1 WHERE goods_no = ?"); // INSERT(stmt3)前処理(ループの外で前処理しておく) java.sql.PreparedStatement stmt3 = con.prepareStatement("INSERT INTO master_t1 VALUES(?, ?)"); // UPDATE(stmt4)前処理(ループの外で前処理しておく) java.sql.PreparedStatement stmt4 = con.prepareStatement("UPDATE master_t1 SET total_quantity = ? WHERE goods_no = ?"); // SELECT(stmt1)入力パラメタ設定 stmt1.setDate(1, fromdate); stmt1.setDate(2, todate); // SELECT(stmt1)実行 java.sql.ResultSet rs1 = stmt1.executeQuery(); while (rs1.next()) { // SELECT(stmt1)検索結果取得 x_goods_no = (Integer)rs1.getObject("goods_no"); x_quantity_1 = rs1.getBigDecimal("quantity_1"); // SELECT(stmt2)入力パラメタ設定 stmt2.setObject(1, x_goods_no); // SELECT(stmt2)実行 java.sql.ResultSet rs2 = stmt2.executeQuery(); // goods_noが登録済/未登録で処理分け if (!rs2.next()) { // 未登録==>新規エントリ追加 // 更新前にSELECT(stmt2)カーソルクローズ rs2.close(); // INSERT(stmt3)入力パラメタ設定 stmt3.setObject(1, x_goods_no); stmt3.setBigDecimal(2, x_quantity_1); // INSERT(stmt3)実行 stmt3.executeUpdate(); } else { // 登録済==>既存エントリ更新 // 現在値取得 x_total_quantity = rs2.getBigDecimal("total_quantity"); // 増分 x_total_quantity = x_total_quantity.add(x_quantity_1); // 更新前にSELECT(stmt2)カーソルクローズ rs2.close(); // UPDATE(stmt4)入力パラメタ設定 stmt4.setBigDecimal(1, x_total_quantity); stmt4.setObject(2, x_goods_no); stmt4.executeUpdate() ; } } // SELECT(stmt1)カーソルクローズ rs1.close(); // 各ステートメントオブジェクト解放 stmt1.close(); stmt2.close(); stmt3.close(); stmt3.close(); // コネクション切断 con.close(); } catch (SQLException ex) { // SQLエラー処理 SQLException fast_ex = ex; System.out.println("\n***** SQLException caught *****\n"); while (ex != null) { System.out.println ("SQLState: " + ex.getSQLState ()); System.out.println ("Message: " + ex.getMessage ()); System.out.println ("Vendor: " + ex.getErrorCode ()); ex.printStackTrace(); ex = ex.getNextException (); System.out.println (""); } System.out.println("*******************************\n"); throw fast_ex; } return; } }
上記の外部Java手続き本体を使用して,Javaストアドプロシジャを定義,実行する例を次に示します。
-
Javaファイルのコンパイル(HP-UXの場合の例です)
javac sample2.java
-
JARファイルの作成(HP-UXの場合の例です)
jar -cvf sample2.jar sample2.class
-
HiRDBへのJARファイルの登録(SQLのINSTALL JARを使用した例です)
INSTALL JAR 'sample2.jar' ;
-
Javaストアドプロシジャの定義
CREATE PROCEDURE jproc1(IN fromdate DATE, IN todate DATE) LANGUAGE JAVA EXTERNAL NAME 'sample2.jar:sample2.jproc1(java.sql.Date, java.sql.Date) returns void' PARAMETER STYLE JAVA end_proc;
-
Javaストアドプロシジャの実行
CALL jproc1(IN ?,IN ?)
(3) サンプル3
gzip,ungzipを使用して,BLOB型データを圧縮,伸長する例です。
-
外部Java関数本体(ファイル名:sample3.java)
/* ALL RIGHTS RESERVED,COPYRIGHT (C)2000,HITACHI,LTD. */ /* LICENSED MATERIAL OF HITACHI,LTD. */ /************************************************************************/ /* name = HiRDB 06-00 Javaストアド サンプル3 */ /************************************************************************/ import java.util.zip.*; import java.io.*; public class sample3 { private final static int BUFF_SIZE = 4096; /*==================================================================*/ /* name = デバッグ用メインメソッド */ /*==================================================================*/ public static void main(String[] args) throws IOException { // 入力データ取得 String sin = args[0]; byte[] bin = args[0].getBytes(); System.out.println("input data : " + sin); // GZIP(BLOB) byte[] bwork = gzip(bin); System.out.println("gzip(BLOB) : " + bin.length + "=>" + bwork.length + "(" + (bwork.length * 100 / bin.length) + "%): " + ""); // GUNZIP(BLOB) byte[] bout = gunzip(bwork); System.out.println("gunzip(BLOB): " + bwork.length + "=>" + bout.length + "(" + (bout.length * 100 / bwork.length) + "%): " + new String(bout)); return; } /*==================================================================*/ /* name = サンプル3メソッド[gzip(BLOB)] */ /*==================================================================*/ public static byte[] gzip(byte indata[]) { // 圧縮データ出力用のストリーム生成 ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 圧縮データ出力 try { GZIPOutputStream zos = new GZIPOutputStream(baos); zos.write(indata, 0, indata.length); zos.close(); baos.close(); } catch (IOException ex) { System.out.println("gzip(BLOB): IOException: " + ex); ex.printStackTrace(); } // 返却値の圧縮後バイト配列生成 byte[] outdata = baos.toByteArray(); return outdata; } /*==================================================================*/ /* name = サンプル3メソッド[gunzip(BLOB)] */ /*==================================================================*/ public static byte[] gunzip(byte[] indata) { int rlen; // 入出力実長 byte[] buff = new byte[BUFF_SIZE]; // 入出力用バッファ // 圧縮データ入力用のストリーム生成 ByteArrayInputStream bais = new ByteArrayInputStream(indata); // 伸長データ出力用のストリーム生成 ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 圧縮データ入力・伸長データ出力 try { GZIPInputStream zis = new GZIPInputStream(bais); while ((rlen = zis.read(buff, 0, buff.length)) >= 0) { baos.write(buff, 0, rlen); } zis.close(); bais.close(); baos.close(); } catch (IOException ex) { System.out.println("gunzip(BLOB): IOException: " + ex); ex.printStackTrace(); } // 返却値の伸長後バイト配列生成 byte[] outdata = baos.toByteArray(); return outdata; } }
上記の外部Java関数本体を使用して,Javaストアドファンクションを定義,実行する例を次に示します。
-
Javaファイルのコンパイル(HP-UXの場合の例です)
javac sample3.java
-
JARファイルの作成(HP-UXの場合の例です)
jar -cvf sample3.jar sample3.class
-
HiRDBへのJARファイルの登録(SQLのINSTALL JARを使用した例です)
INSTALL JAR 'sample3.jar' ;
-
Javaストアドファンクションの定義
CREATE FUNCTION gzip(indata BLOB(1M)) RETURNS BLOB(1M) LANGUAGE JAVA EXTERNAL NAME 'sample3.jar:sample3.gzip(byte[]) returns byte[]' PARAMETER STYLE JAVA end_proc; CREATE FUNCTION gunzip(indata BLOB(1M)) RETURNS BLOB(1M) LANGUAGE JAVA EXTERNAL NAME 'sample3.jar:sample3.gunzip(byte[]) returns byte[]' PARAMETER STYLE JAVA end_proc;
-
Javaストアドファンクションの実行
INSERT INTO t1 values(10, ?, gzip(? AS BLOB(1M))) : SELECT c1, c2, gunzip(c3), length(c2), length(c3) from t1
(4) サンプル4
動的結果集合を使用して,2表の検索した結果を返す例です。
-
外部Java手続き本体(ファイル名:sample4rs.java)
/* ALL RIGHTS RESERVED,COPYRIGHT (C)2000,HITACHI,LTD. */ /* LICENSED MATERIAL OF HITACHI,LTD. */ /************************************************************************/ /* name = HiRDB 06-00 Javaストアド Result Set 導通用ジョブ */ /************************************************************************/ import java.lang.*; import java.math.*; import java.sql.*; /************************************************************************/ /* name = Result Set 導通用クラス(プロシジャ側) */ /************************************************************************/ public class sample4rs { /*==================================================================*/ /* name = デバッグ用メインメソッド */ /*==================================================================*/ public static void main(String args[]) throws SQLException { java.lang.Integer p1 = new Integer(10); int[] cr_cnt = null; java.sql.ResultSet[] rs1 = null; java.sql.ResultSet[] rs2 = null; try { // Driverクラスの登録 Class.forName("JP.co.Hitachi.soft.HiRDB.JDBC.HiRDBDriver"); } catch (ClassNotFoundException ex) { System.out.println("\n***** ClassNotFoundException caught *****\n"); ex.printStackTrace(); System.out.println (""); System.out.println("*******************************\n"); return; } rs_proc(p1, cr_cnt, rs1, rs2); } /*==================================================================*/ /* name = Result Set 導通用メソッド */ /*==================================================================*/ public static void rs_proc(java.lang.Integer p1,int icnt_cr[], java.sql.ResultSet[] rs1, java.sql.ResultSet[] rs2) throws SQLException { java.lang.Integer x_goods_no; java.math.BigDecimal x_quantity_1, x_total_quantity; try { // コネクトオブジェクト生成(Java手続き内ではCONNECTは発行されない) java.sql.Connection con = DriverManager.getConnection("jdbc:hitachi:hirdb"); con.setAutoCommit(false); // 自動コミットの抑止 // SELECT(stmt1)前処理 java.sql.PreparedStatement stmt1 = con.prepareStatement("SELECT c1, c2 FROM rs_t1 WHERE c1 > ?"); // SELECT(stmt1)入力パラメタ設定 stmt1.setInt(1, p1.intValue()); // SELECT(stmt2)前処理 java.sql.PreparedStatement stmt2 = con.prepareStatement("SELECT c1, c2 FROM rs_t2 WHERE c1 > 10"); // SELECT(stmt1)実行 rs1[0] = stmt1.executeQuery(); // SELECT(stmt2)実行 rs2[0] = stmt2.executeQuery(); // 動的結果集合の数 icnt_cr[0] = 2; // SELECT(stmt2)実行(一行だけ取り出す) rs2[0].next(); } catch (SQLException ex) { // SQLエラー処理 SQLException fast_ex = ex; System.out.println("\n***** SQLException caught *****\n"); while (ex != null) { System.out.println ("SQLState: " + ex.getSQLState ()); System.out.println ("Message: " + ex.getMessage ()); System.out.println ("Vendor: " + ex.getErrorCode ()); ex.printStackTrace(); ex = ex.getNextException (); System.out.println (""); } System.out.println("*******************************\n"); throw fast_ex; } return; } }
-
UAP(sample4ap.java)
/* ALL RIGHTS RESERVED,COPYRIGHT (C)2000,HITACHI,LTD. */ /* LICENSED MATERIAL OF HITACHI,LTD. */ /************************************************************************/ /* name = HiRDB 06-00 Javaストアド Result Set 導通用ジョブ */ /************************************************************************/ import java.lang.*; import java.math.*; import java.sql.*; /************************************************************************/ /* name = Result Set 導通用クラス(CALL側) */ /************************************************************************/ public class sample4ap { /*==================================================================*/ /* name = デバッグ用メインメソッド */ /*==================================================================*/ public static void main(String args[]) throws SQLException { try { // Driverクラスの登録 Class.forName("JP.co.Hitachi.soft.HiRDB.JDBC.HiRDBDriver"); } catch (ClassNotFoundException ex) { System.out.println("\n***** ClassNotFoundException caught *****\n"); ex.printStackTrace(); System.out.println (""); System.out.println("*******************************\n"); return; } rs_call(); } /*==================================================================*/ /* name = Result Set 導通用メソッド */ /*==================================================================*/ public static void rs_call() throws SQLException { java.lang.Integer xc1; java.lang.String xc2; int cr_cnt[] = new int[1]; try { // コネクトオブジェクト生成(Java手続き内ではCONNECTは発行されない) java.sql.Connection con = DriverManager.getConnection ("jdbc:hitachi:hirdb", "\"USER1\"", "\"PASS1\""); con.setAutoCommit(false); // 自動コミットの抑止 // CALL(stmt1)前処理 java.sql.CallableStatement stmt1 = con.prepareCall("{CALL rs_proc(?,?)}"); // CALL(stmt1)入力パラメタ設定 stmt1.setInt(1, 10); stmt1.registerOutParameter(2, java.sql.Types.INTEGER); // CALL(stmt1)実行 stmt1.execute(); // CALL(stmt1)出力パラメタ取得 cr_cnt[0] = stmt1.getInt(2); System.out.println("cr_cnt=" + cr_cnt[0] + "\n"); // 動的結果集合の取得 java.sql.ResultSet rs = stmt1.getResultSet(); while (rs.next()) { // SELECT(stmt1)検索結果取得 xc1 = (Integer)rs.getObject("c1"); xc2 = (String)rs.getObject("c2"); System.out.println("xc1=" + xc1 + ",xc2=" + xc2 + "\n"); } // カーソルクローズ rs.close(); if (stmt1.getMoreResults()) { rs = stmt1.getResultSet(); while (rs.next()) { // SELECT(stmt1)検索結果取得 xc1 = (Integer)rs.getObject("c1"); xc2 = (String)rs.getObject("c2"); System.out.println("xc1=" + xc1 + ",xc2=" + xc2 + "\n"); } } // カーソルクローズ rs.close(); // 各ステートメントオブジェクト解放 stmt1.close(); // コネクション切断 con.close(); } catch (SQLException ex) { // SQLエラー処理 SQLException fast_ex = ex; System.out.println("\n***** SQLException caught *****\n"); while (ex != null) { System.out.println ("SQLState: " + ex.getSQLState ()); System.out.println ("Message: " + ex.getMessage ()); System.out.println ("Vendor: " + ex.getErrorCode ()); ex.printStackTrace(); ex = ex.getNextException (); System.out.println (""); } System.out.println("*******************************\n"); throw fast_ex; } return; } }
-
Javaストアドプロシジャの定義
CREATE PROCEDURE rs_proc(IN p1 INT,OUT cr_cnt INT) DYNAMIC RESULT SETS 2 LANGUAGE JAVA EXTERNAL NAME 'sample4.jar:sample4rs.rs_proc(java.lang.Integer, int[], java.sql. ResultSet[], java.sql.ResultSet[]) returns void' PARAMETER STYLE JAVA end_proc;