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 */ 016 package org.opengion.fukurou.db; 017 018 import java.io.IOException; 019 import java.io.Reader; 020 import java.sql.CallableStatement; 021 import java.sql.Clob; 022 import java.sql.Connection; 023 import java.sql.PreparedStatement; 024 import java.sql.ParameterMetaData; 025 import java.sql.ResultSet; 026 import java.sql.ResultSetMetaData; 027 import java.sql.SQLException; 028 import java.sql.Types; 029 import java.util.ArrayList; 030 import java.util.Locale; 031 032 // import java.text.DateFormat; // 5.5.5.4 (2012/08/18) DATE,TIMESTAMP の処?利用時にコメントを外す 033 // import java.text.SimpleDateFormat; // 5.5.5.4 (2012/08/18) DATE,TIMESTAMP の処?利用時にコメントを外す 034 035 import org.opengion.fukurou.util.ApplicationInfo; 036 import org.opengion.fukurou.util.Closer; 037 import org.opengion.fukurou.util.StringUtil; 038 import org.opengion.fukurou.util.HybsDateUtil; 039 040 /** 041 * ??タベ?ス関連の便利なメソ?を集めた簡易ユー?リ?ークラスです? 042 * 全てのメソ?は、static メソ?になって?す? 043 * 044 * @og.rev 2.1.1.1 (2002/11/15) Serializable インターフェースを削除する? 045 * @og.rev 4.0.0.0 (2007/10/16) DBアクセス関係?メソ?のみをパ?ージ移?hayabusa/db ?fukurou/db) 046 * @og.group ??/Shell制御 047 * 048 * @version 4.0 049 * @author Kazuhiko Hasegawa 050 * @since JDK5.0, 051 */ 052 public final class DBUtil { 053 054 /** シス?依存?改行記号をセ?します?4.0.0.0(2007/10/17) */ 055 private static final String CR = System.getProperty( "line.separator" ); 056 057 /** 058 * インスタンスを作らな??で、コンストラクタは、private に設定します? 059 */ 060 private DBUtil() {} 061 062 /** 063 * 初期??タベ?スに接続して、Queryを実行しま?互換性確保?ため残して??? 064 * 065 * ス??トメントと引数により、Prepared クエリーの検索のみ実行します? 066 * 結果は,すべて??に変換されて格納されます? 067 * 068 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設? 069 * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を?"DEFAULT" から null に変更 070 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します? 071 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更 072 * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 073 * 074 * @param stmt ス??トメント文字? 075 * @param args オブジェクト?引数配? 076 * @param appInfo アプリ??オブジェク? 077 * 078 * @return 検索結果の配? 079 */ 080 public static String[][] dbExecute( final String stmt ,final String[] args ,final ApplicationInfo appInfo ) { 081 // return dbExecute( stmt ,args,appInfo,"DEFAULT" ); 082 // return dbExecute( stmt, args, appInfo, null ); 083 084 // Transaction tran = new TransactionReal( null,appInfo ); 085 Transaction tran = new TransactionReal( appInfo ); // 5.3.7.0 (2011/07/01) 引数変更 086 // return dbExecute( stmt, args, tran, null, false ); 087 088 // 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 089 try { 090 return dbExecute( stmt, args, tran, null, false ); 091 } 092 finally { 093 // エラー発生時は、tran.rollback() が呼ばれて?ため、close()時にエラーフラグをセ?する??な?? 094 tran.close(); 095 } 096 } 097 098 /** 099 * 初期??タベ?スに接続して、Queryを実行しま?Transaction 対?? 100 * 101 * ス??トメントと引数により、Prepared クエリーの検索のみ実行します? 102 * 結果は,すべて??に変換されて格納されます? 103 * ここでは、Transactionオブジェクトから?Connection を取り?して使用します? 104 * 105 * @og.rev 5.1.9.0 (2010/08/01) 新規作? Transaction 対? 106 * 107 * @param stmt ス??トメント文字? 108 * @param args オブジェクト?引数配? 109 * @param tran Transactionオブジェク? 110 * 111 * @return 検索結果の配? 112 */ 113 public static String[][] dbExecute( final String stmt ,final String[] args ,final Transaction tran ) { 114 return dbExecute( stmt, args, tran, null, false ); 115 } 116 117 /** 118 * 検索する??タベ?スを指定して、Queryを実行しま?互換性確保?ため残して??? 119 * 120 * ス??トメントと引数により、Prepared クエリーの検索のみ実行します? 121 * 結果は,すべて??に変換されて格納されます? 122 * 追?検索以外?SQLも実行できます?結果は、null を返します? 123 * 124 * @og.rev 3.0.0.0 (2002/12/25) 検索のみのクエリーから、何でもあり?クエリーに変更 125 * @og.rev 2.3.1.3 (2003/01/28) Open Cursor が?大量に残る件の対応?ResultSet ?close() 126 * @og.rev 3.8.0.8 (2005/10/03) エラーメ?ージの出力?をメ?ージ?Queryに変更します? 127 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設? 128 * @og.rev 4.0.0.1 (2007/12/03) try ??catch ??finally をきちんと行う? 129 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します? 130 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更 131 * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 132 * 133 * @param stmt ス??トメント文字? 134 * @param args オブジェクト?引数配? 135 * @param appInfo アプリ??オブジェク? 136 * @param dbid 接続?ID 137 * 138 * @return 検索結果の配? 139 */ 140 public static String[][] dbExecute( final String stmt ,final String[] args, final ApplicationInfo appInfo, final String dbid ) { 141 // return dbExecute( stmt, args, appInfo, dbid, false ); 142 143 // Transaction tran = new TransactionReal( dbid,appInfo ); 144 Transaction tran = new TransactionReal( appInfo ); // 5.3.7.0 (2011/07/01) 引数変更 145 // return dbExecute( stmt, args, tran, dbid, false ); 146 147 // 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 148 try { 149 return dbExecute( stmt, args, tran, dbid, false ); 150 } 151 finally { 152 // エラー発生時は、tran.rollback() が呼ばれて?ため、close()時にエラーフラグをセ?する??な?? 153 tran.close(); 154 } 155 } 156 157 /** 158 * 検索する??タベ?スを指定して、Queryを実行しま?Transaction 対?? 159 * 160 * ス??トメントと引数により、Prepared クエリーの検索のみ実行します? 161 * 結果は,すべて??に変換されて格納されます? 162 * 追?検索以外?SQLも実行できます?結果は、null を返します? 163 * ここでは、Transactionオブジェクトから?Connection を取り?して使用します? 164 * 165 * @og.rev 5.1.9.0 (2010/08/01) 新規作? Transaction 対? 166 * 167 * @param stmt ス??トメント文字? 168 * @param args オブジェクト?引数配? 169 * @param tran Transactionオブジェク? 170 * @param dbid 接続?ID 171 * 172 * @return 検索結果の配? 173 */ 174 public static String[][] dbExecute( final String stmt ,final String[] args, final Transaction tran , final String dbid ) { 175 return dbExecute( stmt, args, tran, dbid, false ); 176 } 177 178 /** 179 * 検索する??タベ?スを指定して、Queryを実行しま?互換性確保?ため残して??? 180 * 181 * ス??トメントと引数により、Prepared クエリーの検索のみ実行します? 182 * 結果は,すべて??に変換されて格納されます? 183 * 追?検索以外?SQLも実行できます?結果は、null を返します? 184 * 185 * @og.rev 4.3.7.0 (2009/06/01) 新規作? 186 * @og.rev 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す?(PostgreSQL対? 187 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します? 188 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更 189 * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 190 * 191 * @param stmt ス??トメント文字? 192 * @param args オブジェクト?引数配? 193 * @param appInfo アプリ??オブジェク? 194 * @param dbid 接続?ID 195 * @param useHeader 1行目にヘッ??を含める? 196 * 197 * @return 検索結果の配? 198 */ 199 public static String[][] dbExecute( final String stmt ,final String[] args, final ApplicationInfo appInfo, final String dbid, final boolean useHeader ) { 200 // Transaction tran = new TransactionReal( dbid,appInfo ); 201 Transaction tran = new TransactionReal( appInfo ); // 5.3.7.0 (2011/07/01) 引数変更 202 // return dbExecute( stmt, args, tran, dbid, useHeader ); 203 204 // 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 205 try { 206 return dbExecute( stmt, args, tran, dbid, useHeader ); 207 } 208 finally { 209 // エラー発生時は、tran.rollback() が呼ばれて?ため、close()時にエラーフラグをセ?する??な?? 210 tran.close(); 211 } 212 } 213 214 /** 215 * 検索する??タベ?スを指定して、Queryを実行しま?Transaction 対?? 216 * 217 * ス??トメントと引数により、Prepared クエリーの検索のみ実行します? 218 * 結果は,すべて??に変換されて格納されます? 219 * 追?検索以外?SQLも実行できます?結果は、null を返します? 220 * 221 * @og.rev 5.1.9.0 (2010/08/01) 新規作? Transaction 対? 222 * @og.rev 5.3.8.0 (2011/08/01) Transaction を引数で受け取った?合?、close() しな?? 223 * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData ?ConnectionFactory経由で取得?(PostgreSQL対?、setNull 対? 224 * 225 * @param stmt ス??トメント文字? 226 * @param args オブジェクト?引数配? 227 * @param tran Transactionオブジェク? 228 * @param dbid 接続?ID 229 * @param useHeader 1行目にヘッ??を含める? 230 * 231 * @return 検索結果の配? 232 */ 233 // public static String[][] dbExecute( final String stmt ,final String[] args, final ApplicationInfo appInfo, final String dbid, final boolean useHeader ) { 234 public static String[][] dbExecute( final String stmt ,final String[] args, final Transaction tran, final String dbid, final boolean useHeader ) { 235 // Connection conn = null; // 5.1.9.0 (2010/08/01) Transaction 対? 236 PreparedStatement pstmt = null; 237 ResultSet resultSet = null; 238 String[][] rtn = null; 239 // boolean errFlag = true; 240 try { 241 // conn = ConnectionFactory.connection( dbid,appInfo ); 242 Connection conn = tran.getConnection( dbid ); // 5.1.9.0 (2010/08/01) Transaction 対? 243 pstmt = conn.prepareStatement( stmt ); 244 if( args != null ) { 245 // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す?(PostgreSQL対? 246 // boolean useParamMetaData = ApplicationInfo.useParameterMetaData( conn ); 247 boolean useParamMetaData = ConnectionFactory.useParameterMetaData( dbid ); // 5.3.8.0 (2011/08/01) 248 if( useParamMetaData ) { 249 ParameterMetaData pMeta = pstmt.getParameterMetaData(); 250 for( int i=0; i<args.length; i++ ) { 251 int type = pMeta.getParameterType( i+1 ); 252 // 5.3.8.0 (2011/08/01) setNull 対? 253 // pstmt.setObject( i+1,args[i],type ); 254 String val = args[i]; 255 if( val == null || val.isEmpty() ) { 256 pstmt.setNull( i+1, type ); 257 } 258 else { 259 pstmt.setObject( i+1, val, type ); 260 } 261 } 262 } 263 else { 264 for( int i=0; i<args.length; i++ ) { 265 pstmt.setObject( i+1,args[i] ); 266 } 267 } 268 } 269 boolean status = pstmt.execute(); 270 if( status ) { 271 resultSet = pstmt.getResultSet(); 272 // rtn = DBUtil.resultToArray( resultSet,false ); 273 rtn = DBUtil.resultToArray( resultSet,useHeader ); // 4.3.7.0 (2009/06/01) 274 } 275 else { 276 // conn.commit(); 277 tran.commit(); // 5.1.9.0 (2010/08/01) Transaction 対? 278 } 279 // errFlag = false; // エラーでな? 280 } 281 catch ( SQLException ex ) { 282 // Closer.rollback( conn ); 283 tran.rollback(); // 5.1.9.0 (2010/08/01) Transaction 対? 284 String errMsg = ex.getMessage() + ":" + ex.getSQLState() + CR 285 + "SQL=[" + stmt + "]" + CR 286 + "ARG=[" + StringUtil.array2csv( args ) + "]" + CR 287 + "DBID=[" + dbid + "]" + CR; 288 throw new RuntimeException( errMsg,ex ); 289 } 290 finally { 291 Closer.resultClose( resultSet ); 292 Closer.stmtClose( pstmt ); 293 294 // if( errFlag ) { ConnectionFactory.remove( conn,dbid ); } 295 // else { ConnectionFactory.close( conn,dbid ); } 296 // 5.3.8.0 (2011/08/01) Transaction を引数で受け取った?合?、close() しな?? 297 // tran.close( errFlag ); // 5.1.9.0 (2010/08/01) Transaction 対? 298 } 299 return rtn; 300 } 301 302 /** 303 * 初期??タベ?スに接続して、CallableStatement(PL/SQL)を実行しま?互換性確保?ため残して??? 304 * ス??トメントと引数により、CallableStatement クエリーを実行します? 305 * 結果は,ス??タスとエラーメ?ージを返します?便宜的に、String配?に 306 * 設定して返します? 307 * ス??トメント文字?には?{ call PLSQL( ?,?,???? ) } となります? 308 * 第?数、第二引数は、OUT属?で、結果(STATUS)とエラー時??(ERR_CODE)を返します? 309 * 第三引数以降? ? には、オブジェクト?引数配? が?に割り当てられます? 310 * 311 * @og.rev 3.8.0.0 (2005/06/07) 新規追? 312 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設? 313 * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を?"DEFAULT" から null に変更 314 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します? 315 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更 316 * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 317 * 318 * @param stmt ス??トメント文字? 319 * @param args オブジェクト?引数配? 320 * @param appInfo アプリ??オブジェク? 321 * 322 * @return 実行結果([0]=ス??タス、[1]=エラーメ?ージ 323 */ 324 public static String[] dbCallExecute( final String stmt ,final String[] args, final ApplicationInfo appInfo ) { 325 // return dbCallExecute( stmt ,args,appInfo,"DEFAULT" ); 326 // return dbCallExecute( stmt ,args, appInfo, null ); 327 328 // Transaction tran = new TransactionReal( null,appInfo ); 329 Transaction tran = new TransactionReal( appInfo ); // 5.3.7.0 (2011/07/01) 引数変更 330 // return dbCallExecute( stmt ,args, tran, null ); 331 332 // 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 333 try { 334 return dbCallExecute( stmt ,args, tran, null ); 335 } 336 finally { 337 // エラー発生時は、tran.rollback() が呼ばれて?ため、close()時にエラーフラグをセ?する??な?? 338 tran.close(); 339 } 340 } 341 342 /** 343 * 初期??タベ?スに接続して、CallableStatement(PL/SQL)を実行しま?Transaction 対?? 344 * ス??トメントと引数により、CallableStatement クエリーを実行します? 345 * 結果は,ス??タスとエラーメ?ージを返します?便宜的に、String配?に 346 * 設定して返します? 347 * ス??トメント文字?には?{ call PLSQL( ?,?,???? ) } となります? 348 * 第?数、第二引数は、OUT属?で、結果(STATUS)とエラー時??(ERR_CODE)を返します? 349 * 第三引数以降? ? には、オブジェクト?引数配? が?に割り当てられます? 350 * 351 * @og.rev 5.1.9.0 (2010/08/01) 新規作? Transaction 対? 352 * 353 * @param stmt ス??トメント文字? 354 * @param args オブジェクト?引数配? 355 * @param tran Transactionオブジェク? 356 * 357 * @return 実行結果([0]=ス??タス、[1]=エラーメ?ージ 358 */ 359 public static String[] dbCallExecute( final String stmt ,final String[] args, final Transaction tran ) { 360 return dbCallExecute( stmt ,args, tran, null ); 361 } 362 363 /** 364 * 検索する??タベ?スを指定して、CallableStatement(PL/SQL)を実行しま?互換性確保?ため残して??? 365 * ス??トメントと引数により、CallableStatement クエリーを実行します? 366 * 結果は,ス??タスとエラーメ?ージを返します?便宜的に、String配?に 367 * 設定して返します? 368 * ス??トメント文字?には?{ call PLSQL( ?,?,???? ) } となります? 369 * 第?数、第二引数は、OUT属?で、結果(STATUS)とエラー時??(ERR_CODE)を返します? 370 * 第三引数以降? ? には、オブジェクト?引数配? が?に割り当てられます? 371 * 検索する??タベ?スは、DEFAULT です? 372 * 373 * @og.rev 3.8.0.0 (2005/06/07) 新規追? 374 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設? 375 * @og.rev 4.0.0.1 (2007/12/03) try ??catch ??finally をきちんと行う? 376 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します? 377 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更 378 * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 379 * 380 * @param stmt ス??トメント文字? 381 * @param args オブジェクト?引数配? 382 * @param appInfo アプリ??オブジェク? 383 * @param dbid 接続?ID 384 * 385 * @return 実行結果([0]=ス??タス、[1]=エラーメ?ージ 386 */ 387 public static String[] dbCallExecute( final String stmt ,final String[] args, final ApplicationInfo appInfo ,final String dbid ) { 388 // Transaction tran = new TransactionReal( dbid,appInfo ); 389 Transaction tran = new TransactionReal( appInfo ); // 5.3.7.0 (2011/07/01) 引数変更 390 // return dbCallExecute( stmt ,args, tran, dbid ); 391 392 // 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 393 try { 394 return dbCallExecute( stmt ,args, tran, dbid ); 395 } 396 finally { 397 // エラー発生時は、tran.rollback() が呼ばれて?ため、close()時にエラーフラグをセ?する??な?? 398 tran.close(); 399 } 400 } 401 402 /** 403 * 検索する??タベ?スを指定して、CallableStatement(PL/SQL)を実行しま?Transaction 対?? 404 * ス??トメントと引数により、CallableStatement クエリーを実行します? 405 * 結果は,ス??タスとエラーメ?ージを返します?便宜的に、String配?に 406 * 設定して返します? 407 * ス??トメント文字?には?{ call PLSQL( ?,?,???? ) } となります? 408 * 第?数、第二引数は、OUT属?で、結果(STATUS)とエラー時??(ERR_CODE)を返します? 409 * 第三引数以降? ? には、オブジェクト?引数配? が?に割り当てられます? 410 * 検索する??タベ?スは、DEFAULT です? 411 * 412 * @og.rev 5.1.9.0 (2010/08/01) 新規作? Transaction 対? 413 * @og.rev 5.3.8.0 (2011/08/01) Transaction を引数で受け取った?合?、close() しな?? 414 * 415 * @param stmt ス??トメント文字? 416 * @param args オブジェクト?引数配? 417 * @param tran Transactionオブジェク? 418 * @param dbid 接続?ID 419 * 420 * @return 実行結果([0]=ス??タス、[1]=エラーメ?ージ 421 */ 422 public static String[] dbCallExecute( final String stmt ,final String[] args, final Transaction tran ,final String dbid ) { 423 // Connection conn = null ; // 5.1.9.0 (2010/08/01) Transaction 対? 424 CallableStatement callStmt = null ; 425 426 String[] rtn = new String[2] ; 427 428 // boolean errFlag = true; 429 try { 430 // conn = ConnectionFactory.connection( dbid,appInfo ); 431 Connection conn = tran.getConnection( dbid ); // 5.1.9.0 (2010/08/01) Transaction 対? 432 callStmt = conn.prepareCall( stmt ); 433 434 callStmt.registerOutParameter( 1, Types.INTEGER ); 435 callStmt.registerOutParameter( 2, Types.VARCHAR ); 436 if( args != null ) { 437 for( int i=0; i<args.length; i++ ) { 438 callStmt.setObject( i+3,args[i] ); 439 } 440 } 441 callStmt.execute(); 442 443 rtn[0] = String.valueOf( callStmt.getInt(1) ); // 結果ス??タス 444 rtn[1] = callStmt.getString(2); // ?(エラーメ?ージ) 445 446 // conn.commit(); 447 tran.commit(); // 5.1.9.0 (2010/08/01) Transaction 対? 448 // errFlag = false; // エラーでな? 449 } 450 catch ( SQLException ex ) { 451 // Closer.rollback( conn ); 452 tran.rollback(); // 5.1.9.0 (2010/08/01) Transaction 対? 453 String errMsg = ex.getMessage() + ":" + ex.getSQLState() + CR 454 + "SQL=[" + stmt + "]" + CR 455 + "ARG=[" + StringUtil.array2csv( args ) + "]" + CR 456 + "DBID=[" + dbid + "]" + CR; 457 throw new RuntimeException( errMsg,ex ); 458 } 459 finally { 460 Closer.stmtClose( callStmt ); 461 // if( errFlag ) { ConnectionFactory.remove( conn,dbid ); } 462 // else { ConnectionFactory.close( conn,dbid ); } 463 // 5.3.8.0 (2011/08/01) Transaction を引数で受け取った?合?、close() しな?? 464 // tran.close( errFlag ); // 5.1.9.0 (2010/08/01) Transaction 対? 465 } 466 return rtn; 467 } 468 469 /** 470 * SQL??実行結果において、データの件数を取得しま?互換性確保?ため残して??? 471 * ス??トメントと引数により、Prepared クエリーの検索を実行します? 472 * 結果は、件数を数値で返します? 473 * あくまで、存在チェ?に?な処??み行って?ため??常の検索より高?です? 474 * 475 * @og.rev 3.5.0.0 (2003/09/17) 新規作? 476 * @og.rev 3.8.0.8 (2005/10/03) エラーメ?ージの出力?をメ?ージ?Queryに変更します? 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 * @og.rev 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す?(PostgreSQL対? 480 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します? 481 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更 482 * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 483 * 484 * @param stmt ス??トメント文字? 485 * @param args オブジェクト?引数配? 486 * @param appInfo アプリ??オブジェク? 487 * @param dbid 接続?ID 488 * 489 * @return 検索結果(??タの件数) 490 */ 491 public static int dbExist( final String stmt ,final String[] args, final ApplicationInfo appInfo , final String dbid ) { 492 // Transaction tran = new TransactionReal( dbid,appInfo ); 493 Transaction tran = new TransactionReal( appInfo ); // 5.3.7.0 (2011/07/01) 引数変更 494 // return dbExist( stmt ,args, tran , dbid ); 495 496 // 5.3.8.0 (2011/08/01) TransactionReal と close() 処?セ?で実行する? 497 try { 498 return dbExist( stmt ,args, tran , dbid ); 499 } 500 finally { 501 // エラー発生時は、tran.rollback() が呼ばれて?ため、close()時にエラーフラグをセ?する??な?? 502 tran.close(); 503 } 504 } 505 506 /** 507 * SQL??実行結果において、データの件数を取得しま?Transaction 対?? 508 * ス??トメントと引数により、Prepared クエリーの検索を実行します? 509 * 結果は、件数を数値で返します? 510 * あくまで、存在チェ?に?な処??み行って?ため??常の検索より高?です? 511 * 512 * @og.rev 5.1.9.0 (2010/08/01) 新規作? Transaction 対? 513 * @og.rev 5.3.8.0 (2011/08/01) Transaction を引数で受け取った?合?、close() しな?? 514 * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData ?ConnectionFactory経由で取得?(PostgreSQL対?、setNull 対? 515 * 516 * @param stmt ス??トメント文字? 517 * @param args オブジェクト?引数配? 518 * @param tran Transactionオブジェク? 519 * @param dbid 接続?ID 520 * 521 * @return 検索結果(??タの件数) 522 */ 523 public static int dbExist( final String stmt ,final String[] args, final Transaction tran , final String dbid ) { 524 // Connection conn = null; // 5.1.9.0 (2010/08/01) Transaction 対? 525 PreparedStatement pstmt = null; 526 ResultSet resultSet = null; 527 int rtnCnt = -1; 528 529 // boolean errFlag = true; 530 try { 531 // conn = ConnectionFactory.connection( dbid,appInfo ); 532 Connection conn = tran.getConnection( dbid ); // 5.1.9.0 (2010/08/01) Transaction 対? 533 pstmt = conn.prepareStatement( stmt ); 534 if( args != null ) { 535 // 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す?(PostgreSQL対? 536 // boolean useParamMetaData = ApplicationInfo.useParameterMetaData( conn ); 537 boolean useParamMetaData = ConnectionFactory.useParameterMetaData( dbid ); // 5.3.8.0 (2011/08/01) 538 if( useParamMetaData ) { 539 ParameterMetaData pMeta = pstmt.getParameterMetaData(); 540 for( int i=0; i<args.length; i++ ) { 541 int type = pMeta.getParameterType( i+1 ); 542 // 5.3.8.0 (2011/08/01) setNull 対? 543 // pstmt.setObject( i+1,args[i],type ); 544 String val = args[i]; 545 if( val == null || val.isEmpty() ) { 546 pstmt.setNull( i+1, type ); 547 } 548 else { 549 pstmt.setObject( i+1, val, type ); 550 } 551 } 552 } 553 else { 554 for( int i=0; i<args.length; i++ ) { 555 pstmt.setObject( i+1,args[i] ); 556 } 557 } 558 } 559 560 resultSet = pstmt.executeQuery(); 561 if( resultSet.next() ) { 562 rtnCnt = resultSet.getInt(1); 563 } 564 // errFlag = false; // エラーでな? 565 } 566 catch ( SQLException ex ) { 567 String errMsg = ex.getMessage() + ":" + ex.getSQLState() + CR 568 + "SQL=[" + stmt + "]" + CR 569 + "ARG=[" + StringUtil.array2csv( args ) + "]" + CR 570 + "DBID=[" + dbid + "]" + CR; 571 throw new RuntimeException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び?更 572 } 573 finally { 574 Closer.resultClose( resultSet ); 575 Closer.stmtClose( pstmt ); 576 577 // if( errFlag ) { ConnectionFactory.remove( conn,dbid ); } 578 // else { ConnectionFactory.close( conn,dbid ); } 579 // 5.3.8.0 (2011/08/01) Transaction を引数で受け取った?合?、close() しな?? 580 // tran.close( errFlag ); // 5.1.9.0 (2010/08/01) Transaction 対? 581 } 582 return rtnCnt; 583 } 584 585 /** 586 * ResultSet より、結果の??配?を作?します? 587 * 588 * 結果は,すべて??に変換されて格納されます? 589 * 移動したメソ?で使われて?のでこれも移? 590 * 591 * @og.rev 3.1.0.0 (2003/03/20) Vector を使用して??で?同期でも構わな??を?ArrayList に置換え? 592 * @og.rev 3.8.0.8 (2005/10/03) エラーメ?ージの出力?をメ?ージ?Queryに変更します? 593 * @og.rev 4.0.0.0 (2005/01/31) private ?public , ヘッ????の取得有無フラグの追? 594 * @og.rev 5.6.7.0 (2013/07/27) CLOB 対? 595 * 596 * @param resultSet ResultSetオブジェク? 597 * @param useHeader true:ヘッ??を第?に含める/false:含めな? 598 * 599 * @return ResultSetの検索結果配? 600 */ 601 public static String[][] resultToArray( final ResultSet resultSet,final boolean useHeader ) { 602 ArrayList<String[]> data = new ArrayList<String[]>(); 603 try { 604 ResultSetMetaData metaData = resultSet.getMetaData(); 605 int numberOfColumns = metaData.getColumnCount(); 606 607 String[] columnNames = new String[numberOfColumns]; 608 // 5.6.7.0 (2013/07/27) CLOB 対? 609 int[] type = new int[numberOfColumns]; 610 boolean useClob = false; // そもそも、CLOB系のカラ?あるかど? 611 for( int i = 0; i < numberOfColumns; i++ ) { 612 int tp = metaData.getColumnType( i+1 ); 613 type[i] = tp ; 614 if( tp == Types.CLOB || tp == Types.ROWID || tp == Types.TIMESTAMP ) { useClob = true; } 615 if( useHeader ) { 616 columnNames[i] = ( metaData.getColumnLabel(i+1) ).toUpperCase(Locale.JAPAN) ; 617 } 618 } 619 620 if( useHeader ) { data.add( columnNames ); } 621 622 // 5.6.7.0 (2013/07/27) CLOB 対?で、??ーループを回すので、??法を変更 623 // if( useHeader ) { 624 // String[] columnNames = new String[numberOfColumns]; 625 // for( int column = 0; column < numberOfColumns; column++ ) { 626 // columnNames[column] = ( metaData.getColumnLabel(column+1) ).toUpperCase(Locale.JAPAN) ; 627 // } 628 // data.add( columnNames ); 629 // } 630 631 // 5.6.7.0 (2013/07/27) CLOB 対応?つ?に、ループカウンタを?0からに変更します? 632 while( resultSet.next() ) { 633 String[] columnValues = new String[numberOfColumns]; 634 for( int i = 0; i < numberOfColumns; i++ ) { 635 Object obj = resultSet.getObject(i+1); 636 if( obj == null ) { 637 columnValues[i] = ""; 638 } 639 else if( useClob ) { 640 columnValues[i] = getValue( resultSet, i ,type[i] ); 641 } 642 else { 643 columnValues[i] = String.valueOf( obj ); 644 } 645 } 646 data.add( columnValues ); 647 } 648 649 // while( resultSet.next() ) { 650 // String[] columnValues = new String[numberOfColumns]; 651 // for( int i = 1; i <= numberOfColumns; i++ ) { 652 // Object obj = resultSet.getObject(i); 653 // if( obj == null ) { 654 // columnValues[i-1] = ""; 655 // } 656 // else { 657 // columnValues[i-1] = String.valueOf( obj ); 658 // } 659 // } 660 // data.add( columnValues ); 661 // } 662 } 663 catch ( SQLException ex ) { 664 String errMsg = "処?果を実行できませんでした? 665 + CR + ex.getMessage() ; 666 throw new RuntimeException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び?更 667 } 668 669 int size = data.size(); 670 String[][] rtn = new String[size][]; 671 for( int i=0; i<size; i++ ) { 672 rtn[i] = data.get(i); 673 } 674 675 return rtn; 676 } 677 678 /** 679 * 検索結果オブジェクトから?を取り?します? 680 * 681 * @og.rev 5.3.6.0 (2011/06/01) ?機?対応によりメソ?? 682 * @og.rev 5.5.5.4 (2012/08/18) if?case?置き換え? 683 * @og.rev 5.5.5.4 (2012/08/18) TIMESTAMP の処?追?? 684 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します? 685 * 686 * @param res 検索結果オブジェク? 687 * @param col カラ?0から始まる?。このメソ?の?で?1して?? 688 * @param type ??タタイ?java.sql.Types.XXXX) 689 * 690 * @return 値 691 * @throws SQLException ??タベ?スアクセスエラー 692 */ 693 public static String getValue( final ResultSet res, final int col, final int type ) throws SQLException { 694 String val = null; 695 696 Object obj = res.getObject(col+1); 697 if( obj == null ) { 698 val = ""; 699 } 700 else { 701 switch( type ) { 702 case Types.CLOB : val = getClobData( (Clob)obj ) ; break; 703 case Types.ROWID: val = res.getString(col+1); break; 704 // case Types.TIMESTAMP : val = DATE_FMT.format( (java.sql.Timestamp)obj ); break; 705 case Types.TIMESTAMP : val = HybsDateUtil.getDate( ((java.sql.Timestamp)obj).getTime() , "yyyyMMddHHmmss" ); break; 706 default : val = String.valueOf( obj ); 707 } 708 } 709 710 return val; 711 712 // 5.5.5.4 (2012/08/18) if?case?置き換? 713 // if( type == Types.CLOB ) { 714 // Object obj = res.getObject(col+1); 715 // val = getClobData( (Clob)obj ) ; 716 // } 717 // else if( type == Types.ROWID ) { 718 // String obj = res.getString(col+1); 719 // if( obj == null ) { 720 // val = ""; 721 // } 722 // else { 723 // val = obj; 724 // } 725 // } 726 // else { 727 // Object obj = res.getObject(col+1); 728 // if( obj == null ) { 729 // val = ""; 730 // } 731 // else { 732 // val = String.valueOf( obj ); 733 // } 734 // } 735 // 736 // return val; 737 } 738 739 // 5.5.5.4 (2012/08/18) DATE,TIMESTAMP の処?追? 740 // private static final DateFormat DATE_FMT = new SimpleDateFormat( "yyyyMMddHHmmss",Locale.JAPAN ); 741 742 /** 743 * コネクションオブジェクトからデータベ?スのProductNameを取り?します? 744 * ProductName は、小文字化して返します? 745 * また?処?ラーが発生した?合??none" を返します? 746 * ここでは、SQLException は、発生させません? 747 * 748 * @og.rev 5.6.7.0 (2013/07/27) 新規追? 749 * @og.rev 5.6.7.4 (2013/08/30) ProductNameの小文字化対? 750 * 751 * @param conn コネクションオブジェク? 752 * 753 * @return ??タベ?スのProductName 754 */ 755 public static String getProductName( final Connection conn ) { 756 String dbName ; 757 try { 758 // dbName = conn.getMetaData().getDatabaseProductName(); 759 dbName = conn.getMetaData().getDatabaseProductName().toLowerCase( Locale.JAPAN ); // 5.6.7.4 (2013/08/30) 760 } 761 catch( SQLException ex ) { 762 dbName = "none"; 763 } 764 return dbName ; 765 } 766 767 /** 768 * Clob オブジェクトから文字?を取り?します? 769 * 770 * @og.rev 5.3.6.0 (2011/06/01) 新規作? 771 * 772 * @param clobData Clobオブジェク? 773 * 774 * @return Clobオブジェクトから取り?した?? 775 * @throws SQLException ??タベ?スアクセスエラー 776 */ 777 private static String getClobData( final Clob clobData ) throws SQLException { 778 if( clobData == null ) { return ""; } 779 780 Reader reader = null; 781 StringBuilder buf = new StringBuilder( 10000 ); 782 783 try { 784 reader = clobData.getCharacterStream(); 785 char[] ch = new char[10000]; 786 int len ; 787 while( (len = reader.read( ch )) >= 0 ) { 788 buf.append( ch,0,len ); 789 } 790 } 791 catch( IOException ex ) { 792 String errMsg = "CLOB??タの読み込みに失敗しました?; 793 // throw new HybsSystemException( errMsg,ex ); 794 throw new RuntimeException( errMsg,ex ); 795 } 796 finally { 797 Closer.ioClose( reader ); 798 } 799 return buf.toString(); 800 } 801 }