    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.fukurou.db;
    017
    018import java.sql.CallableStatement;
    019import java.sql.Connection;
    020import java.sql.PreparedStatement;
    021import java.sql.ParameterMetaData;
    022import java.sql.ResultSet;
    023import java.sql.SQLException;
    024import java.sql.Types;
    025import java.util.ArrayList;
    026import java.util.Locale;
    027
    028import org.opengion.fukurou.system.OgRuntimeException ;                         // 6.4.2.0 (2016/01/29)
    029import org.opengion.fukurou.util.StringUtil;
    030import static org.opengion.fukurou.system.HybsConst.CR;                         // 6.1.0.0 (2014/12/26) refactoring
    031import static org.opengion.fukurou.system.HybsConst.DB_FETCH_SIZE;      // 6.9.4.1 (2018/04/09)
    032
    033/**
    034 * データベース関連の便利なメソッドを集めた簡易ユーティリティークラスです。
    035 * 全てのメソッドは、static メソッドになっています。
    036 *
    037 * @og.rev 2.1.1.1 (2002/11/15) Serializable インターフェースを削除する。
    038 * @og.rev 4.0.0.0 (2007/10/16) DBアクセス関係のメソッドのみをパッケージ移動(hayabusa/db ⇒ fukurou/db)
    039 * @og.rev 6.0.4.0 (2014/11/28) ResultSetValue クラスで、ResultSet から値を取得する処理を移植
    040 *
    041 * @og.group ＤＢ/Shell制御
    042 *
    043 * @version  4.0
    044 * @author   Kazuhiko Hasegawa
    045 * @since    JDK5.0,
    046 */
    047public final class DBUtil {
    048//      /** 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズ  {@value} */
    049//      private static final int DB_FETCH_SIZE = 1001 ;
    050
    051        /**
    052         * インスタンスを作らないので、コンストラクタは、private に設定します。
    053         */
    054        private DBUtil() {}
    055
    056        /**
    057         * 初期データベースに接続して、Queryを実行します(互換性確保のため残しています)。
    058         *
    059         * ステートメントと引数により、Prepared クエリーの検索のみ実行します。
    060         * 結果は,すべて文字列に変換されて格納されます。
    061         *
    062         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    063         * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
    064         * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します。
    065         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
    066         * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処理をセットで実行する。
    067         * @og.rev 6.3.6.1 (2015/08/28) Transaction でAutoCloseableを使用したtry-with-resources構築に対応。
    068         *
    069         * @param   stmt ステートメント文字列
    070         * @param   args オブジェクトの引数配列
    071         * @param   appInfo アプリ情報オブジェクト
    072         *
    073         * @return  検索結果の配列
    074         */
    075        public static String[][] dbExecute( final String stmt ,final String[] args ,final ApplicationInfo appInfo ) {
    076                try( final Transaction tran = new TransactionReal( appInfo ) ) {
    077                        return dbExecute( stmt, args, tran, null, false );
    078                }
    079        }
    080
    081        /**
    082         * 初期データベースに接続して、Queryを実行します(Transaction 対応)。
    083         *
    084         * ステートメントと引数により、Prepared クエリーの検索のみ実行します。
    085         * 結果は,すべて文字列に変換されて格納されます。
    086         * ここでは、Transactionオブジェクトから、Connection を取り出して使用します。
    087         *
    088         * @og.rev 5.1.9.0 (2010/08/01) 新規作成 Transaction 対応
    089         *
    090         * @param   stmt ステートメント文字列
    091         * @param   args オブジェクトの引数配列
    092         * @param   tran Transactionオブジェクト
    093         *
    094         * @return  検索結果の配列
    095         */
    096        public static String[][] dbExecute( final String stmt ,final String[] args ,final Transaction tran ) {
    097                return dbExecute( stmt, args, tran, null, false );
    098        }
    099
    100        /**
    101         * 検索するデータベースを指定して、Queryを実行します(互換性確保のため残しています)。
    102         *
    103         * ステートメントと引数により、Prepared クエリーの検索のみ実行します。
    104         * 結果は,すべて文字列に変換されて格納されます。
    105         * 追加：検索以外のSQLも実行できます。結果は、null を返します。
    106         *
    107         * @og.rev 3.0.0.0 (2002/12/25) 検索のみのクエリーから、何でもありのクエリーに変更
    108         * @og.rev 2.3.1.3 (2003/01/28) Open Cursor が、大量に残る件の対応。ResultSet を close()
    109         * @og.rev 3.8.0.8 (2005/10/03) エラーメッセージの出力順をメッセージ＋Queryに変更します。
    110         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    111         * @og.rev 4.0.0.1 (2007/12/03) try ～ catch ～ finally をきちんと行う。
    112         * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します。
    113         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
    114         * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処理をセットで実行する。
    115         * @og.rev 6.3.6.1 (2015/08/28) Transaction でAutoCloseableを使用したtry-with-resources構築に対応。
    116         *
    117         * @param   stmt ステートメント文字列
    118         * @param   args オブジェクトの引数配列
    119         * @param   appInfo アプリ情報オブジェクト
    120         * @param   dbid 接続先ID
    121         *
    122         * @return  検索結果の配列
    123         */
    124        public static String[][] dbExecute( final String stmt ,final String[] args, final ApplicationInfo appInfo, final String dbid ) {
    125                try( final Transaction tran = new TransactionReal( appInfo ) ) {
    126                        return dbExecute( stmt, args, tran, dbid, false  );
    127                }
    128        }
    129
    130        /**
    131         * 検索するデータベースを指定して、Queryを実行します(Transaction 対応)。
    132         *
    133         * ステートメントと引数により、Prepared クエリーの検索のみ実行します。
    134         * 結果は,すべて文字列に変換されて格納されます。
    135         * 追加：検索以外のSQLも実行できます。結果は、null を返します。
    136         * ここでは、Transactionオブジェクトから、Connection を取り出して使用します。
    137         *
    138         * @og.rev 5.1.9.0 (2010/08/01) 新規作成 Transaction 対応
    139         *
    140         * @param   stmt ステートメント文字列
    141         * @param   args オブジェクトの引数配列
    142         * @param   tran Transactionオブジェクト
    143         * @param   dbid 接続先ID
    144         *
    145         * @return  検索結果の配列
    146         */
    147        public static String[][] dbExecute( final String stmt ,final String[] args, final Transaction tran , final String dbid ) {
    148                return dbExecute( stmt, args, tran, dbid, false );
    149        }
    150
    151        /**
    152         * 検索するデータベースを指定して、Queryを実行します(互換性確保のため残しています)。
    153         *
    154         * ステートメントと引数により、Prepared クエリーの検索のみ実行します。
    155         * 結果は,すべて文字列に変換されて格納されます。
    156         * 追加：検索以外のSQLも実行できます。結果は、null を返します。
    157         *
    158         * @og.rev 4.3.7.0 (2009/06/01) 新規作成
    159         * @og.rev 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
    160         * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します。
    161         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
    162         * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処理をセットで実行する。
    163         * @og.rev 6.3.6.1 (2015/08/28) Transaction でAutoCloseableを使用したtry-with-resources構築に対応。
    164         *
    165         * @param   stmt ステートメント文字列
    166         * @param   args オブジェクトの引数配列
    167         * @param   appInfo アプリ情報オブジェクト
    168         * @param   dbid 接続先ID
    169         * @param   useHeader 1行目にヘッダーを含めるか
    170         *
    171         * @return  検索結果の配列
    172         */
    173        public static String[][] dbExecute( final String stmt ,final String[] args, final ApplicationInfo appInfo, final String dbid, final boolean useHeader ) {
    174                try( final Transaction tran = new TransactionReal( appInfo ) ) {
    175                        return dbExecute( stmt, args, tran, dbid, useHeader );
    176                }
    177        }
    178
    179        /**
    180         * 検索するデータベースを指定して、Queryを実行します(Transaction 対応)。
    181         *
    182         * ステートメントと引数により、Prepared クエリーの検索のみ実行します。
    183         * 結果は,すべて文字列に変換されて格納されます。
    184         * 追加：検索以外のSQLも実行できます。結果は、null を返します。
    185         *
    186         * @og.rev 5.1.9.0 (2010/08/01) 新規作成 Transaction 対応
    187         * @og.rev 5.3.8.0 (2011/08/01) Transaction を引数で受け取った場合は、close() しない。
    188         * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData を ConnectionFactory経由で取得。(PostgreSQL対応)、setNull 対応
    189         * @og.rev 6.4.2.1 (2016/02/05) try-with-resources 文で記述。
    190         * @og.rev 6.4.3.2 (2016/02/19) args が null でなく、length==0 でない場合のみ、処理する。
    191         * @og.rev 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズを設定。
    192         *
    193         * @param   stmt ステートメント文字列
    194         * @param   args オブジェクトの引数配列
    195         * @param   tran Transactionオブジェクト
    196         * @param   dbid 接続先ID
    197         * @param   useHeader 1行目にヘッダーを含めるか
    198         *
    199         * @return  検索結果の配列
    200         */
    201        public static String[][] dbExecute( final String stmt ,final String[] args, final Transaction tran, final String dbid, final boolean useHeader ) {
    202                String[][] rtn = null;
    203                try {
    204                        final Connection conn = tran.getConnection( dbid );                             // 5.1.9.0 (2010/08/01) Transaction 対応
    205                        try( final PreparedStatement pstmt = conn.prepareStatement( stmt ) ) {
    206                                pstmt.setFetchSize( DB_FETCH_SIZE );                            // 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズ
    207
    208                                // 6.4.3.2 (2016/02/19) args が null でなく、length==0 でない場合のみ、処理する。
    209                                if( args != null && args.length > 0 ) {
    210                                        // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
    211                                        final boolean useParamMetaData = ConnectionFactory.useParameterMetaData( dbid );        // 5.3.8.0 (2011/08/01)
    212                                        if( useParamMetaData ) {
    213                                                final ParameterMetaData pMeta = pstmt.getParameterMetaData();
    214                                                for( int i=0; i<args.length; i++ ) {
    215                                                        final int type = pMeta.getParameterType( i+1 );
    216                                                        // 5.3.8.0 (2011/08/01) setNull 対応
    217                                                        final String val = args[i];
    218                                                        if( val == null || val.isEmpty() ) {
    219                                                                pstmt.setNull( i+1, type );
    220                                                        }
    221                                                        else {
    222                                                                pstmt.setObject( i+1, val, type );
    223                                                        }
    224                                                }
    225                                        }
    226                                        else {
    227                                                for( int i=0; i<args.length; i++ ) {
    228                                                        pstmt.setObject( i+1,args[i] );
    229                                                }
    230                                        }
    231                                }
    232                                if( pstmt.execute() ) {                                                                 // 6.1.0.0 (2014/12/26) refactoring
    233                                        try( final ResultSet resultSet = pstmt.getResultSet() ) {
    234                                                rtn = DBUtil.resultToArray( resultSet,useHeader );      // 4.3.7.0 (2009/06/01)
    235                                        }
    236                                }
    237                                // 6.3.6.1 (2015/08/28) 検索・登録関係なく、commit() する。
    238                                tran.commit();                  // 5.1.9.0 (2010/08/01) Transaction 対応
    239                        }
    240                }
    241                catch( final SQLException ex ) {
    242                        tran.rollback();                        // 5.1.9.0 (2010/08/01) Transaction 対応
    243                        final String errMsg = ex.getMessage() + ":" + ex.getSQLState() + CR
    244                                                        + "SQL=[" + stmt + "]" + CR
    245                                                        + "ARG=[" + StringUtil.array2csv( args ) + "]" + CR
    246                                                        + "DBID=[" + dbid + "]" + CR;
    247                        throw new OgRuntimeException( errMsg,ex );
    248                }
    249                return rtn;
    250        }
    251
    252        /**
    253         * 初期データベースに接続して、CallableStatement(PL/SQL)を実行します(互換性確保のため残しています)。
    254         * ステートメントと引数により、CallableStatement クエリーを実行します。
    255         * 結果は,ステータスとエラーメッセージを返します。便宜的に、String配列に
    256         * 設定して返します。
    257         * ステートメント文字列には、 { call PLSQL( ?,?,?･･･ ) } となります。
    258         * 第一引数、第二引数は、OUT属性で、結果(STATUS)とエラー時の内容(ERR_CODE)を返します。
    259         * 第三引数以降の ? には、オブジェクトの引数配列 が順に割り当てられます。
    260         *
    261         * @og.rev 3.8.0.0 (2005/06/07) 新規追加
    262         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    263         * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
    264         * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します。
    265         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
    266         * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処理をセットで実行する。
    267         * @og.rev 6.3.6.1 (2015/08/28) Transaction でAutoCloseableを使用したtry-with-resources構築に対応。
    268         *
    269         * @param   stmt ステートメント文字列
    270         * @param   args オブジェクトの引数配列
    271         * @param   appInfo アプリ情報オブジェクト
    272         *
    273         * @return  実行結果([0]=ステータス、[1]=エラーメッセージ
    274         */
    275        public static String[] dbCallExecute( final String stmt ,final String[] args, final ApplicationInfo appInfo ) {
    276                try( final Transaction tran = new TransactionReal( appInfo ) ) {
    277                        return dbCallExecute( stmt ,args, tran, null );
    278                }
    279        }
    280
    281        /**
    282         * 初期データベースに接続して、CallableStatement(PL/SQL)を実行します(Transaction 対応)。
    283         * ステートメントと引数により、CallableStatement クエリーを実行します。
    284         * 結果は,ステータスとエラーメッセージを返します。便宜的に、String配列に
    285         * 設定して返します。
    286         * ステートメント文字列には、 { call PLSQL( ?,?,?･･･ ) } となります。
    287         * 第一引数、第二引数は、OUT属性で、結果(STATUS)とエラー時の内容(ERR_CODE)を返します。
    288         * 第三引数以降の ? には、オブジェクトの引数配列 が順に割り当てられます。
    289         *
    290         * @og.rev 5.1.9.0 (2010/08/01) 新規作成 Transaction 対応
    291         *
    292         * @param   stmt ステートメント文字列
    293         * @param   args オブジェクトの引数配列
    294         * @param   tran Transactionオブジェクト
    295         *
    296         * @return  実行結果([0]=ステータス、[1]=エラーメッセージ
    297         */
    298        public static String[] dbCallExecute( final String stmt ,final String[] args, final Transaction tran ) {
    299                return dbCallExecute( stmt ,args, tran, null );
    300        }
    301
    302        /**
    303         * 検索するデータベースを指定して、CallableStatement(PL/SQL)を実行します(互換性確保のため残しています)。
    304         * ステートメントと引数により、CallableStatement クエリーを実行します。
    305         * 結果は,ステータスとエラーメッセージを返します。便宜的に、String配列に
    306         * 設定して返します。
    307         * ステートメント文字列には、 { call PLSQL( ?,?,?･･･ ) } となります。
    308         * 第一引数、第二引数は、OUT属性で、結果(STATUS)とエラー時の内容(ERR_CODE)を返します。
    309         * 第三引数以降の ? には、オブジェクトの引数配列 が順に割り当てられます。
    310         * 検索するデータベースは、DEFAULT です。
    311         *
    312         * @og.rev 3.8.0.0 (2005/06/07) 新規追加
    313         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    314         * @og.rev 4.0.0.1 (2007/12/03) try ～ catch ～ finally をきちんと行う。
    315         * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します。
    316         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
    317         * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処理をセットで実行する。
    318         * @og.rev 6.3.6.1 (2015/08/28) Transaction でAutoCloseableを使用したtry-with-resources構築に対応。
    319         *
    320         * @param   stmt ステートメント文字列
    321         * @param   args オブジェクトの引数配列
    322         * @param   appInfo アプリ情報オブジェクト
    323         * @param   dbid 接続先ID
    324         *
    325         * @return  実行結果([0]=ステータス、[1]=エラーメッセージ
    326         */
    327        public static String[] dbCallExecute( final String stmt ,final String[] args, final ApplicationInfo appInfo ,final String dbid ) {
    328                try( final Transaction tran = new TransactionReal( appInfo ) ) {
    329                        return dbCallExecute( stmt ,args, tran, dbid );
    330                }
    331        }
    332
    333        /**
    334         * 検索するデータベースを指定して、CallableStatement(PL/SQL)を実行します(Transaction 対応)。
    335         * ステートメントと引数により、CallableStatement クエリーを実行します。
    336         * 結果は,ステータスとエラーメッセージを返します。便宜的に、String配列に
    337         * 設定して返します。
    338         * ステートメント文字列には、 { call PLSQL( ?,?,?･･･ ) } となります。
    339         * 第一引数、第二引数は、OUT属性で、結果(STATUS)とエラー時の内容(ERR_CODE)を返します。
    340         * 第三引数以降の ? には、オブジェクトの引数配列 が順に割り当てられます。
    341         * 検索するデータベースは、DEFAULT です。
    342         *
    343         * @og.rev 5.1.9.0 (2010/08/01) 新規作成 Transaction 対応
    344         * @og.rev 5.3.8.0 (2011/08/01) Transaction を引数で受け取った場合は、close() しない。
    345         * @og.rev 6.4.2.1 (2016/02/05) try-with-resources 文で記述。
    346         * @og.rev 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズを設定。
    347         *
    348         * @param   stmt ステートメント文字列
    349         * @param   args オブジェクトの引数配列
    350         * @param   tran Transactionオブジェクト
    351         * @param   dbid 接続先ID
    352         *
    353         * @return  実行結果([0]=ステータス、[1]=エラーメッセージ
    354         */
    355        public static String[] dbCallExecute( final String stmt ,final String[] args, final Transaction tran ,final String dbid ) {
    356
    357                String[] rtn = new String[2] ;
    358
    359                try {
    360                        final Connection conn = tran.getConnection( dbid );                             // 5.1.9.0 (2010/08/01) Transaction 対応
    361                        try( final CallableStatement callStmt = conn.prepareCall( stmt ) ) {
    362                                callStmt.setFetchSize( DB_FETCH_SIZE );                                         // 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズ
    363
    364                                callStmt.registerOutParameter( 1, Types.INTEGER );
    365                                callStmt.registerOutParameter( 2, Types.VARCHAR );
    366                                if( args != null ) {
    367                                        for( int i=0; i<args.length; i++ ) {
    368                                                callStmt.setObject( i+3,args[i] );
    369                                        }
    370                                }
    371                                callStmt.execute();
    372
    373                                rtn[0] = String.valueOf( callStmt.getInt(1) );  // 結果ステータス
    374                                rtn[1] = callStmt.getString(2);                                 // 内容(エラーメッセージ)
    375
    376                                tran.commit();                                  // 5.1.9.0 (2010/08/01) Transaction 対応
    377                        }
    378                }
    379                catch( final SQLException ex ) {
    380                        tran.rollback();                                // 5.1.9.0 (2010/08/01) Transaction 対応
    381                        final String errMsg = ex.getMessage() + ":" + ex.getSQLState() + CR
    382                                                        + "SQL=[" + stmt + "]" + CR
    383                                                        + "ARG=[" + StringUtil.array2csv( args ) + "]" + CR
    384                                                        + "DBID=[" + dbid + "]" + CR;
    385                        throw new OgRuntimeException( errMsg,ex );
    386                }
    387                return rtn;
    388        }
    389
    390        /**
    391         * SQL文の実行結果において、データの件数を取得します(互換性確保のため残しています)。
    392         * ステートメントと引数により、Prepared クエリーの検索を実行します。
    393         * 結果は、件数を数値で返します。
    394         * あくまで、存在チェックに必要な処理のみ行っているため、通常の検索より高速です。
    395         *
    396         * @og.rev 3.5.0.0 (2003/09/17) 新規作成
    397         * @og.rev 3.8.0.8 (2005/10/03) エラーメッセージの出力順をメッセージ＋Queryに変更します。
    398         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    399         * @og.rev 4.0.0.1 (2007/12/03) try ～ catch ～ finally をきちんと行う。
    400         * @og.rev 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
    401         * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応します。
    402         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
    403         * @og.rev 5.3.8.0 (2011/08/01) TransactionReal と close() 処理をセットで実行する。
    404         * @og.rev 6.3.6.1 (2015/08/28) Transaction でAutoCloseableを使用したtry-with-resources構築に対応。
    405         *
    406         * @param   stmt ステートメント文字列
    407         * @param   args オブジェクトの引数配列
    408         * @param   appInfo アプリ情報オブジェクト
    409         * @param   dbid 接続先ID
    410         *
    411         * @return  検索結果(データの件数)
    412         */
    413        public static int dbExist( final String stmt ,final String[] args, final ApplicationInfo appInfo , final String dbid ) {
    414                try( final Transaction tran = new TransactionReal( appInfo ) ) {
    415                        return dbExist( stmt ,args, tran , dbid );
    416                }
    417        }
    418
    419        /**
    420         * SQL文の実行結果において、データの件数を取得します(Transaction 対応)。
    421         * ステートメントと引数により、Prepared クエリーの検索を実行します。
    422         * 結果は、件数を数値で返します。
    423         * あくまで、存在チェックに必要な処理のみ行っているため、通常の検索より高速です。
    424         *
    425         * @og.rev 5.1.9.0 (2010/08/01) 新規作成 Transaction 対応
    426         * @og.rev 5.3.8.0 (2011/08/01) Transaction を引数で受け取った場合は、close() しない。
    427         * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData を ConnectionFactory経由で取得。(PostgreSQL対応)、setNull 対応
    428         * @og.rev 6.4.2.1 (2016/02/05) try-with-resources 文で記述。
    429         * @og.rev 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズを設定。
    430         *
    431         * @param   stmt ステートメント文字列
    432         * @param   args オブジェクトの引数配列
    433         * @param   tran Transactionオブジェクト
    434         * @param   dbid 接続先ID
    435         *
    436         * @return  検索結果(データの件数)
    437         */
    438        public static int dbExist( final String stmt ,final String[] args, final Transaction tran , final String dbid ) {
    439                int rtnCnt = -1;
    440
    441                try {
    442                        final Connection conn = tran.getConnection( dbid );                             // 5.1.9.0 (2010/08/01) Transaction 対応
    443                        try( final PreparedStatement pstmt = conn.prepareStatement( stmt ) ) {
    444                                pstmt.setFetchSize( DB_FETCH_SIZE );                                            // 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズ
    445                                if( args != null ) {
    446                                        // 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
    447                                        final boolean useParamMetaData = ConnectionFactory.useParameterMetaData( dbid );        // 5.3.8.0 (2011/08/01)
    448                                        if( useParamMetaData ) {
    449                                                final ParameterMetaData pMeta = pstmt.getParameterMetaData();
    450                                                for( int i=0; i<args.length; i++ ) {
    451                                                        final int type = pMeta.getParameterType( i+1 );
    452                                                        // 5.3.8.0 (2011/08/01) setNull 対応
    453                                                        final String val = args[i];
    454                                                        if( val == null || val.isEmpty() ) {
    455                                                                pstmt.setNull( i+1, type );
    456                                                        }
    457                                                        else {
    458                                                                pstmt.setObject( i+1, val, type );
    459                                                        }
    460                                                }
    461                                        }
    462                                        else {
    463                                                for( int i=0; i<args.length; i++ ) {
    464                                                        pstmt.setObject( i+1,args[i] );
    465                                                }
    466                                        }
    467                                }
    468                                try( final ResultSet resultSet = pstmt.executeQuery() ) {
    469                                        if( resultSet.next() ) {
    470                                                rtnCnt = resultSet.getInt(1);
    471                                        }
    472                                }
    473                        }
    474                        tran.commit();                          // 6.3.6.1 (2015/08/28) 検索・登録関係なく、commit() する。
    475                }
    476                catch( final SQLException ex ) {
    477                        tran.rollback();                        // 6.3.6.1 (2015/08/28) 検索・登録関係なく処理する。
    478                        final String errMsg = ex.getMessage() + ":" + ex.getSQLState() + CR
    479                                                        + "SQL=[" + stmt + "]" + CR
    480                                                        + "ARG=[" + StringUtil.array2csv( args ) + "]" + CR
    481                                                        + "DBID=[" + dbid + "]" + CR;
    482                        throw new OgRuntimeException( errMsg,ex );              // 3.5.5.4 (2004/04/15) 引数の並び順変更
    483                }
    484                return rtnCnt;
    485        }
    486
    487        /**
    488         * ResultSet より、結果の文字列配列を作成します。
    489         *
    490         * 結果は,すべて文字列に変換されて格納されます。
    491         * 移動したメソッドで使われているのでこれも移動
    492         *
    493         * @og.rev 3.1.0.0 (2003/03/20) Vector を使用している箇所で、非同期でも構わない箇所を、ArrayList に置換え。
    494         * @og.rev 3.8.0.8 (2005/10/03) エラーメッセージの出力順をメッセージ＋Queryに変更します。
    495         * @og.rev 4.0.0.0 (2005/01/31) private ⇒ public , ヘッダー情報の取得有無フラグの追加
    496         * @og.rev 5.6.7.0 (2013/07/27) CLOB 対応
    497         * @og.rev 6.0.4.0 (2014/11/28) ResultSetValue クラスで、ResultSet から値を取得する処理を行う。
    498         *
    499         * @param   resultSet ResultSetオブジェクト
    500         * @param   useHeader true:ヘッダーを第一行に含める/false:含めない
    501         *
    502         * @return  ResultSetの検索結果配列
    503         * @throws      java.sql.SQLException データベース・アクセス・エラーが発生した場合
    504         */
    505        public static String[][] resultToArray( final ResultSet resultSet,final boolean useHeader ) throws SQLException {
    506                final ArrayList<String[]> data = new ArrayList<>();
    507
    508                final ResultSetValue rsv = new ResultSetValue( resultSet );
    509
    510                if( useHeader ) { data.add( rsv.getNames() ); }
    511
    512                while( rsv.next() ) {
    513                        data.add( rsv.getValues() );
    514                }
    515
    516                final int size = data.size();
    517                String[][] rtn = new String[size][];
    518                for( int i=0; i<size; i++ ) {
    519                        rtn[i] = data.get(i);
    520                }
    521
    522                return rtn;
    523        }
    524
    525        /**
    526         * コネクションオブジェクトからデータベースのProductNameを取り出します。
    527         * ProductName は、小文字化して返します。
    528         * また、処理エラーが発生した場合は、"none" を返します。
    529         * ここでは、SQLException は、発生させません。
    530         *
    531         * @og.rev 5.6.7.0 (2013/07/27) 新規追加
    532         * @og.rev 5.6.7.4 (2013/08/30) ProductNameの小文字化対応
    533         * @og.rev 6.7.4.2 (2017/02/24) ProductNameの大文字化対応
    534         *
    535         * @param conn コネクションオブジェクト
    536         *
    537         * @return データベースのProductName
    538         */
    539        public static String getProductName( final Connection conn ) {
    540                String dbName ;
    541                try {
    542                        dbName = conn.getMetaData().getDatabaseProductName().toUpperCase( Locale.JAPAN );       // 6.7.4.2 (2017/02/24)
    543                }
    544                catch( final SQLException ex ) {
    545                        dbName = "none";
    546                }
    547                return dbName ;
    548        }
    549}