001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.hayabusa.report; 017 018import org.opengion.hayabusa.common.HybsSystem; 019import org.opengion.hayabusa.common.HybsSystemException; 020import org.opengion.fukurou.db.ConnectionFactory; 021import org.opengion.fukurou.db.DBUtil; // 5.5.5.1 (2012/08/07) 022import org.opengion.fukurou.util.StringUtil; 023import org.opengion.fukurou.util.FileUtil; 024import org.opengion.fukurou.util.ApplicationInfo; 025import org.opengion.fukurou.util.Closer; 026 027import java.io.File; 028import java.io.IOException; 029import java.util.List; 030import java.util.Arrays; 031 032import java.sql.Connection; 033import java.sql.PreparedStatement; 034import java.sql.SQLException; 035 036/** 037 * 【EXCEL取込】雛形EXCELシートと、データEXCELシートから、指定のDBにデータを登録するクラスクラスです。 038 * 雛形EXCELシートは、{@カラム} で記述されており、このカラムのEXCEL上のセルの位置を元に、 039 * データEXCELシートから所定のデータを読みこみ、雛形明細定義(GE57)で指定のテーブルに 040 * 抜き出したデータを登録します。 041 * 雛形明細定義(GE57)では、システムID+帳票ID+シート番号をキーに、読み取る対応シートや 042 * シート毎にヘッダーテーブル、明細テーブルの指定、繰返必須カラムのしていなどにより、 043 * 読取る方式と、書き込むテーブルを指定します。 044 * 045 * @og.rev 3.8.0.0 (2005/06/07) 新規追加 046 * @og.group 帳票システム 047 * 048 * @version 4.0 049 * @author Kazuhiko Hasegawa 050 * @since JDK5.0, 051 */ 052public class ExcelInsert { 053 private static final String CR = HybsSystem.CR ; 054 055 private final StringBuilder errMsg ; 056 057 // DBTableReport に対して設定する情報 058 private final String EXCELIN ; // EXCEL ファイルの取込DIR ファイル名は、要求番号.xls 059 060 // 受け渡し変数 061 private final String SYSTEM_ID ; 062 private final String YKNO ; 063 private final String LISTID ; 064 private final boolean DEBUG ; // 3.8.5.0 (2006/03/06) デバッグ用のフラグを追加 065 066 // GE54,GE57 帳票定義、明細情報 067 private String MODELDIR = null; // GE54 雛形EXCELディレクトリ 068 private String MODELFILE = null; // GE54 雛形EXCELファイル名 069 private String[] SHEETNO = null; // GE57 雛形EXCELシート番号 070 private String[] SHEETREF = null; // GE57 データEXCELシート番号 071 private String[] HEADDBID = null; // GE57 ヘッダーテーブル 072 private String[] BODYDBID = null; // GE57 明細テーブル 073 private String[] LOOPCLM = null; // GE57 繰返必須カラム名 074 075 private ExcelLayout layout = null; 076 077 // GE54,GE57 の帳票定義情報を取得するSQL文です。 078 private static final String GE54_GE57_SELECT = 079 "SELECT A.MODELDIR,A.MODELFILE,B.SHEETNO,B.SHEETREF,B.HEADDBID,B.BODYDBID,B.LOOPCLM" + 080 " FROM GE54 A INNER JOIN GE57 B" + 081 " ON A.SYSTEM_ID = B.SYSTEM_ID AND A.LISTID = B.LISTID" + 082 " WHERE A.FGJ = '1' AND B.FGJ = '1'" + 083 " AND A.SYSTEM_ID = ?" + 084 " AND A.LISTID = ?" + 085 " ORDER BY B.SHEETNO" ; 086 087 /** コネクションにアプリケーション情報を追記するかどうか指定 */ 088 public static final boolean USE_DB_APPLICATION_INFO = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ; 089 090 // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 091 private final ApplicationInfo appInfo; 092 private final String DBID = HybsSystem.sys( "RESOURCE_DBID" ); // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応 093 094 /** 095 * コンストラクター 096 * 引数を受けとって、インスタンスを作成します。 097 * 098 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 099 * 100 * @param system_id システムID 101 * @param ykno 要求番号 102 * @param listId 帳票ID 103 * @param excelinDir 出力ディレクトリ 104 * @param debug デバッグフラグ 105 */ 106 public ExcelInsert( final String system_id, final String ykno, final String listId, final String excelinDir, final boolean debug ) { 107 SYSTEM_ID = system_id; 108 YKNO = ykno; 109 LISTID = listId; 110 EXCELIN = excelinDir; 111 DEBUG = debug; 112 errMsg = new StringBuilder(); 113 114 // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 115 if( USE_DB_APPLICATION_INFO ) { 116 appInfo = new ApplicationInfo(); 117 // ユーザーID,IPアドレス,ホスト名 118 appInfo.setClientInfo( SYSTEM_ID,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME ); 119 // 画面ID,操作,プログラムID 120 appInfo.setModuleInfo( "ExcelInsert",YKNO,LISTID ); 121 } 122 else { 123 appInfo = null; 124 } 125 } 126 127 /** 128 * 変換処理を実行します。 129 * 130 * @og.rev 3.8.0.9 (2005/10/17) エラーメッセージ強化 131 * 132 * @return 結果 [true:正常/false:異常] 133 */ 134 public boolean execute() { 135 System.out.print( "ExcelInsert Started ... " ); 136 boolean flag ; 137 138 try { 139 // 初期化 GE54,GE57 帳票定義マスタより必要な情報を取得します。 140 flag = initialDataSet(); 141 if( flag ) { System.out.print( "INIT," ); } 142 143 // 雛型ファイルの存在チェックを行います。 144 // 3.5.4.9 (2004/02/25) 存在チェックエラー(原因不明)の暫定対応 145 File templateExcel = null; 146 if( flag ) { 147 templateExcel = FileUtil.checkFile( MODELDIR, MODELFILE + ".xls" ); 148 flag = templateExcel != null ; // チェックの結果が null なら、見つからなかった。 149 // 3.8.0.9 (2005/10/17) エラーメッセージ強化 150 if( flag ) { System.out.print( "MDL IN," ); } 151 else { 152 errMsg.append( "ExcelInsert MODELFILE Not Found Error!" ).append( CR ); 153 errMsg.append( "==============================" ).append( CR ); 154 errMsg.append( "MODELDIR=" ).append( MODELDIR ).append( CR ) ; 155 errMsg.append( "MODELFILE=" ).append( MODELFILE ).append( ".xls" ) ; 156 errMsg.append( CR ) ; 157 } 158 } 159 160 // EXCELデータファイルの存在チェックを行います。 161 File inputExcel = null; 162 if( flag ) { 163 inputExcel = FileUtil.checkFile( EXCELIN, YKNO + ".xls" ); 164 flag = inputExcel != null ; // チェックの結果が null なら、見つからなかった。 165 // 3.8.0.9 (2005/10/17) エラーメッセージ強化 166 if( flag ) { System.out.print( "XLS IN," ); } 167 else { 168 errMsg.append( "ExcelInsert EXCELIN Not Found Error!" ).append( CR ); 169 errMsg.append( "==============================" ).append( CR ); 170 errMsg.append( "DIR=" ).append( EXCELIN ).append( CR ) ; 171 errMsg.append( "FILE=" ).append( YKNO ).append( ".xls" ) ; 172 errMsg.append( CR ) ; 173 } 174 } 175 176 // 雛形ファイルより、処理対象行列を読み取ります。 177 if( flag ) { 178 flag = getModelData( templateExcel ); 179 if( flag ) { System.out.print( "MDL DT," ); } 180 } 181 182 // EXCELデータファイルを読取り、データベースに書き込みます。 183 if( flag ) { 184 flag = readAndInsertDB( inputExcel ); 185 if( flag ) { System.out.print( "IN DB," ); } 186 } 187 } 188 catch ( RuntimeException ex ) { 189 errMsg.append( "ExcelInsert Execute Exception Error!" ).append( CR ); 190 errMsg.append( "==============================" ).append( CR ); 191 errMsg.append( StringUtil.stringStackTrace( ex ) ) ; 192 errMsg.append( CR ) ; 193 flag = false; 194 } 195 196 System.out.println( "End." ); 197 return flag ; 198 } 199 200 /** 201 * 初期データセットを行います。 202 * ここでは、GE54,GE57 テーブルより必要な情報を取得します。 203 * 204 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 205 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 206 * 207 * @return 結果 [true:正常/false:異常] 208 */ 209 private boolean initialDataSet() { 210 String[] args = new String[] { SYSTEM_ID,LISTID }; 211 // A.MODELDIR,A.MODELFILE,B.SHEETNO,B.SHEETREF,B.HEADDBID,B.BODYDBID,B.LOOPCLM 212 String[][] vals = DBUtil.dbExecute( GE54_GE57_SELECT,args,appInfo, DBID ); // 3.8.7.0 (2006/12/15) 213 if( vals == null || vals.length == 0 ) { 214 errMsg.append( "Data does not exist in GE54 table." ).append( CR ); 215 errMsg.append( "==============================" ).append( CR ); 216 errMsg.append( "SYSTEM_ID=[" ).append( SYSTEM_ID ).append( "] , " ); 217 errMsg.append( "LISTID=[" ).append( LISTID ).append( "]" ); 218 errMsg.append( CR ); 219 return false; 220 } 221 222 int maxRow = vals.length; // 先の条件判断で、最低 1 件以上存在する。 223 MODELDIR = StringUtil.nval( vals[0][0],MODELDIR ); 224 MODELFILE = StringUtil.nval( vals[0][1],MODELFILE ); 225 226 if( MODELDIR == null || MODELDIR.length() == 0 || 227 MODELFILE == null || MODELFILE.length() == 0 ) { 228 errMsg.append( "MODELDIR and MODELFILE is necessary in GE54 table." ).append( CR ); 229 errMsg.append( "==============================" ).append( CR ); 230 errMsg.append( "SYSTEM_ID=[" ).append( SYSTEM_ID ).append( "] , " ); 231 errMsg.append( "LISTID=[" ).append( LISTID ).append( "] , " ); 232 errMsg.append( "MODELDIR=[" ).append( MODELDIR ).append( "] , " ); 233 errMsg.append( "MODELFILE=[" ).append( MODELFILE ).append( "] " ); 234 errMsg.append( CR ); 235 return false; 236 } 237 238 SHEETNO = new String[maxRow]; 239 SHEETREF = new String[maxRow]; 240 HEADDBID = new String[maxRow]; 241 BODYDBID = new String[maxRow]; 242 LOOPCLM = new String[maxRow]; 243 244 for( int row=0; row<maxRow; row++ ) { 245 SHEETNO[row] = StringUtil.nval( vals[row][2],null ); 246 SHEETREF[row] = StringUtil.nval( vals[row][3],null ); 247 HEADDBID[row] = StringUtil.nval( vals[row][4],null ); 248 BODYDBID[row] = StringUtil.nval( vals[row][5],null ); 249 LOOPCLM[row] = StringUtil.nval( vals[row][6],null ); 250 251 // SHEETNO と SHEETREF は、どちら『も』必須 252 // HEADDBID と BODYDBID は、どちら『か』必須 253 if( SHEETNO[row] == null || SHEETREF[row] == null || 254 ( HEADDBID[row] == null && BODYDBID[row] == null ) ) { 255 errMsg.append( "SHEETNO と SHEETREF は、どちら『も』必須" ).append( CR ); 256 errMsg.append( "HEADDBID と BODYDBID は、どちら『か』必須" ).append( CR ); 257 errMsg.append( "==============================" ).append( CR ); 258 errMsg.append( "SYSTEM_ID=[" ).append( SYSTEM_ID ).append( "] , " ); 259 errMsg.append( "LISTID=[" ).append( LISTID ).append( "] , " ); 260 errMsg.append( "SHEETNO=[" ).append( SHEETNO[row] ).append( "] , " ); 261 errMsg.append( "SHEETREF=[" ).append( SHEETREF[row] ).append( "] , " ); 262 errMsg.append( "HEADDBID=[" ).append( HEADDBID[row] ).append( "] , " ); 263 errMsg.append( "BODYDBID=[" ).append( BODYDBID[row] ).append( "] " ); 264 errMsg.append( CR ); 265 return false; 266 } 267 } 268 269 return true; 270 } 271 272 /** 273 * 雛形ファイルより、対象行列を読み取ります。 274 * 275 * @param file 雛形ファイル 276 * 277 * @return 結果 [true:正常/false:異常] 278 */ 279 private boolean getModelData( final File file ) { 280 try { 281 layout = HybsHSSFListener.makeExcelLayout( file,false ); 282 } 283 catch( IOException ex ) { 284 errMsg.append( "Template Excel File can not ModelData." ).append( CR ); 285 errMsg.append( "==============================" ).append( CR ); 286 errMsg.append( "File=" ).append( file.getAbsolutePath() ); 287 errMsg.append( StringUtil.stringStackTrace( ex ) ); 288 errMsg.append( CR ); 289 return false; 290 } 291 292 return true; 293 } 294 295 /** 296 * EXCELを読取り、データベースに書き込みます。 297 * 298 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 299 * 300 * @param file EXCELファイル 301 * 302 * @return 結果 [true:正常/false:異常] 303 */ 304 private boolean readAndInsertDB( final File file ) { 305 306 ExcelDataPickup pickup = new ExcelDataPickup( layout,file,DEBUG ); 307 308 // 実際のデータシートの枚数 309 int sheetSize = pickup.getSheetSize(); 310 // SHEETREF に対して、実際に割り当てなおしたシート対応 311 int[] reference = makeSheetReference( sheetSize,SHEETREF ); 312 313 DatabaseExecute exec = new DatabaseExecute(); 314 exec.setApplicationInfo( appInfo ); // 3.8.7.0 (2006/12/15) 315 int ykno = Integer.parseInt(YKNO) ; 316 for( int shNo=0; shNo<sheetSize; shNo++ ) { 317 int ref = reference[shNo]; 318 if( ref < 0 ) { continue; } // 処理対象外 319 320 pickup.execute( Integer.parseInt( SHEETNO[ref] ),shNo,LOOPCLM[ref] ) ; 321 322 String headerQuery = layout.getHeaderInsertQuery( HEADDBID[ref] ); 323 if( headerQuery != null ) { 324 exec.setStatement( headerQuery ); 325 326 String[] headerData = layout.getHeaderInsertData( SYSTEM_ID,ykno,shNo ); 327 exec.dbExecute( headerData ); 328 } 329 330 String bodyQuery = layout.getBodyInsertQuery( BODYDBID[ref] ); 331 if( bodyQuery != null ) { 332 exec.setStatement( bodyQuery ); 333 334 List<String[]> bodyData = layout.getBodyInsertData( SYSTEM_ID,ykno,shNo ); 335 for( int j=0; j<bodyData.size(); j++ ) { 336 exec.dbExecute( bodyData.get(j) ); 337 } 338 } 339 } 340 exec.commit(); 341 pickup.close(); 342 343 return true; 344 } 345 346 /** 347 * GE57 に指定のSHEETNOとSHEETREF配列より、実際にアクセスするシート番号に対応したリファレンス配列を求めます。 348 * SHEETNO は、雛形EXCELの使用するシート番号を指定します。SHEETREFは、その雛形シートを 349 * 利用して処理するデータEXCELのシートを指定します。シート番号は、0から始まります。 350 * この、データEXCELシート(SHEETREF)は、単一数、カンマ結合、LAST文字 で指定します。 351 * 単一数:雛形シートと1対1で対応するデータEXCELシート番号 352 * カンマ結合:3,4,5 や、2,5 などの複数シートをひとつの雛形シートで処理する場合に設定します。 353 * LAST文字:5,LAST や LAST と記述することで、それ以降の全データシートを雛形シートで処理します。 354 * 355 * ここでは、SHEETREF配列 を実際のデータEXCELシート数分の配列に再配置し、その元のアドレスを 356 * 指すリファレンス情報を返します。 357 * このリファレンス情報を元に、SHEETNO,HEADDBID,BODYDBID,LOOPCLM などの元の配列にアクセスし、 358 * 設定値を取得してきます。 359 * 360 * 例) 361 * SHEETNO = { "1","2" ,"3","4" ,"6" }; 362 * SHEETREF = { "1","2,6","4","5,3","8,LAST" }; 363 * HEADDBID = { "A","B" ,"C","D" ,"E" }; 364 * データシート数=11 365 * 366 * i=[0] , No=[1], REF=[1] 367 * i=[1] , No=[2], REF=[2,6] 368 * i=[2] , No=[3], REF=[4] 369 * i=[3] , No=[4], REF=[5,3] 370 * i=[4] , No=[6], REF=[8,LAST] 371 * ========================= 372 * REF=[0] , Ref=[-1], SHEETNO[] = - , HEADDBID[] = - 373 * REF=[1] , Ref=[0], SHEETNO[[0]]=[1] , HEADDBID[[0]]=[A] 374 * REF=[2] , Ref=[1], SHEETNO[[1]]=[2] , HEADDBID[[1]]=[B] 375 * REF=[3] , Ref=[3], SHEETNO[[3]]=[4] , HEADDBID[[3]]=[D] 376 * REF=[4] , Ref=[2], SHEETNO[[2]]=[3] , HEADDBID[[2]]=[C] 377 * REF=[5] , Ref=[3], SHEETNO[[3]]=[4] , HEADDBID[[3]]=[D] 378 * REF=[6] , Ref=[1], SHEETNO[[1]]=[2] , HEADDBID[[1]]=[B] 379 * REF=[7] , Ref=[-1], SHEETNO[] = - , HEADDBID[] = - 380 * REF=[8] , Ref=[4], SHEETNO[[4]]=[6] , HEADDBID[[4]]=[E] 381 * REF=[9] , Ref=[4], SHEETNO[[4]]=[6] , HEADDBID[[4]]=[E] 382 * REF=[10] , Ref=[4], SHEETNO[[4]]=[6] , HEADDBID[[4]]=[E] 383 * 384 * @param size データシートの総件数 385 * @param sheetRef データEXCELシートの対応する配列(単一数、カンマ結合、LAST文字 が使用可能) 386 * 387 * @return データ件数分に再配置した、雛形EXCELシート番号配列。使用しない場合は、-1 がセット。 388 */ 389 private int[] makeSheetReference( final int size,final String[] sheetRef ) { 390 391 int[] reference = new int[size]; 392 Arrays.fill( reference ,-1 ); 393 394 int maxNo = -1; 395 for( int i=0; i<sheetRef.length; i++ ) { 396 String[] temp = StringUtil.csv2Array( sheetRef[i] ); 397 for( int j=0; j<temp.length; j++ ) { 398 if( temp[j].equals( "LAST" ) ) { 399 for( int k=maxNo; k<size; k++ ) { 400 reference[k] = i ; 401 } 402 i=size; 403 break; 404 } 405 else { 406 int no = Integer.parseInt(temp[j]) ; 407 if( no < size ) { 408 reference[no] = i ; 409 if( maxNo < no ) { maxNo = no+1; } 410 } 411 else { 412 String errMsg = "データシートと雛形明細定義の対応ができません。" 413 + " データシート総件数=[" + size + "] " 414 + " sheetRef[" + i + "]=" + sheetRef[i] ; 415 throw new HybsSystemException( errMsg ); 416 } 417 } 418 } 419 } 420 return reference ; 421 } 422 423 /** 424 * エラーが存在した場合に、エラーメッセージを返します。 425 * 426 * @return エラーメッセージ String 427 */ 428 public String getErrMsg() { 429 return errMsg.toString(); 430 } 431} 432 433/** 434 * 連続した データベース処理を行う為の、管理処理クラスです。 435 * ExcelInsert でのコーディングを分けるためだけのクラスです。 436 * 437 * オブジェクト作成時に、DEFAULT 接続を内部にキープし、setStatement( String )で 438 * PreparedStatementオブジェクトを作成します。このメソッドを呼ぶまでは、 439 * 同じ PreparedStatementオブジェクトを使い続けます。 440 * dbExecute( String[] ) メソッドで、PreparedStatement に設定する引数配列をセットします。 441 * この段階では、commit も、PreparedStatementのclose も行いませんので、連続して、 442 * dbExecute( String[] ) メソッドを呼び出すことが可能です。 443 * 最後に、commit() で、Connection は、プールに返されます。 444 * 445 * エラー時は、rollback() して、Connection は、破棄されます。 446 * 447 * @og.group 帳票システム 448 * 449 * @version 4.0 450 * @author Kazuhiko Hasegawa 451 * @since JDK5.0, 452 */ 453class DatabaseExecute { 454 // 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更 455 private static final String DBID = null ; 456 457 private Connection conn = null; 458 private PreparedStatement pstmt = null; 459 private String tempSql = null; // エラー時にSQL文を表示させる場合に使用します。 460 private ApplicationInfo appInfo = null; 461 462 /** 463 * アクセスログ取得の為,ApplicationInfoオブジェクトを設定します。 464 * 465 * @og.rev 3.8.7.0 (2006/12/15) 新規追加 466 * 467 * @param appInfo ApplicationInfo 468 */ 469 public void setApplicationInfo( final ApplicationInfo appInfo ) { 470 this.appInfo = appInfo; 471 } 472 473 /** 474 * PreparedStatementオブジェクトを作成します。 475 * 次に、このメソッドを呼ぶまでは、同じ PreparedStatementオブジェクトを使い続けます。 476 * 477 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 478 * @og.rev 4.0.0.1 (2007/12/03) try ~ catch ~ finally をきちんと行う。 479 * 480 * @param stmt String 481 */ 482 public void setStatement( final String stmt ) { 483 boolean errFlag = true ; 484 tempSql = stmt; 485 try { 486 // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 487 if( conn == null ) { conn = ConnectionFactory.connection( DBID,appInfo ); } 488 Closer.stmtClose( pstmt ); 489 pstmt = conn.prepareStatement( stmt ); 490 errFlag = false ; 491 } 492 catch (SQLException ex) { 493 String errMsg = "Statement を作成できませんでした。" + HybsSystem.CR 494 + "SQL=[" + stmt + "]" 495 + ex.getMessage() + ":" + ex.getSQLState() ; 496 throw new HybsSystemException( errMsg,ex ); 497 } 498 finally { 499 if( errFlag ) { errorFinally(); } 500 } 501 } 502 503 /** 504 * Connection を commit します。 505 * このオブジェクトを終了する最後に行います。 506 * 507 */ 508 public void commit() { 509 boolean errFlag = true ; 510 try { 511 conn.commit(); 512 errFlag = false ; 513 } 514 catch (SQLException ex) { 515 Closer.rollback( conn ); 516 String errMsg = "Connection をコミットできませんでした。" + HybsSystem.CR 517 + ex.getMessage() + ":" + ex.getSQLState() ; 518 throw new HybsSystemException( errMsg,ex ); 519 } 520 finally { 521 Closer.stmtClose( pstmt ); 522 if( errFlag ) { ConnectionFactory.remove( conn,DBID ); } 523 else { ConnectionFactory.close( conn,DBID ); } 524 conn = null; 525 } 526 } 527 528 /** 529 * PreparedStatement に設定する引数配列をセットします。 530 * 531 * この段階では、commit も、PreparedStatementのclose も行いませんので、連続して、 532 * dbExecute( String[] ) メソッドを呼び出すことが可能です。 533 * 534 * @param args オブジェクトの引数配列 535 */ 536 public void dbExecute( final String[] args ) { 537 // System.out.println( StringUtil.array2csv( args ) ); 538 539 boolean errFlag = true ; 540 try { 541 for( int i=0; i<args.length; i++ ) { 542 pstmt.setString( i+1,args[i] ); 543 } 544 pstmt.execute(); 545 errFlag = false ; 546 } 547 catch (SQLException ex) { 548 String errMsg = "データベース処理を実行できませんでした。" + HybsSystem.CR 549 + "ARGS=[" + StringUtil.array2csv( args ) + "]" + HybsSystem.CR 550 + "SQL=[" + tempSql + "]" 551 + ex.getMessage() + ":" + ex.getSQLState() ; 552 throw new HybsSystemException( errMsg,ex ); 553 } 554 finally { 555 if( errFlag ) { errorFinally(); } 556 } 557 } 558 559 /** 560 * エラー発生時の処理 561 * 562 * PreparedStatement のクローズと、Connection の破棄を行います。 563 */ 564 private void errorFinally() { 565 Closer.stmtClose( pstmt ); 566 pstmt = null; 567 Closer.rollback( conn ); 568 ConnectionFactory.remove( conn,DBID ); 569 conn = null; 570 } 571}