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