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 * また?処?ラーが発生した?合??none" を返します?
748 * SQLException は、発生させません?
749 *
750 * @og.rev 5.6.7.0 (2013/07/27) 新規追?
751 *
752 * @param conn コネクションオブジェク?
753 *
754 * @return ??タベ?スのProductName
755 */
756 public static String getProductName( final Connection conn ) {
757 String dbName ;
758 try {
759 dbName = conn.getMetaData().getDatabaseProductName();
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 }