OSDN Git Service

Ver8.5.2.0
[opengion/opengionV8.git] / uap / webapps / gf / src / org / opengion / fukurou / db / DBSimpleTable.java
1 /*
2  * Copyright (c) 2009 The openGion Project.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific language
14  * governing permissions and limitations under the License.
15  */
16 package org.opengion.fukurou.db;
17
18 import org.opengion.fukurou.util.StringUtil;
19 import org.opengion.fukurou.system.OgRuntimeException ;                         // 6.4.2.0 (2016/01/29)
20 import org.opengion.fukurou.system.Closer;
21 import org.opengion.fukurou.model.Formatter;
22 import org.opengion.fukurou.model.ArrayDataModel;
23 import org.opengion.fukurou.model.DataModel;                                            // 8.2.1.0 (2022/07/15)
24 import static org.opengion.fukurou.system.HybsConst.CR;                         // 6.1.0.0 (2014/12/26) refactoring
25 import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;      // 6.1.0.0 (2014/12/26) refactoring
26
27 import java.sql.Connection;
28 import java.sql.PreparedStatement;
29 import java.sql.ParameterMetaData;
30 import java.sql.SQLException;
31
32 import java.util.Arrays;
33
34 /**
35  * DBTableModel インターフェースを継承した TableModel の実装クラスです。
36  * sql文を execute( query ) する事により、データベースを検索した結果を
37  * DBTableModel に割り当てます。
38  *
39  * メソッドを宣言しています
40  * DBTableModel インターフェースは、データベースの検索結果(Resultset)をラップする
41  * インターフェースとして使用して下さい。
42  *
43  * @og.rev 5.2.2.0 (2010/11/01) パッケージ移動(hayabusa.db ⇒ fukurou.db)
44  * @og.group DB/Shell制御
45  *
46  * @version     4.0
47  * @author      Kazuhiko Hasegawa
48  * @since       JDK5.0,
49  */
50 public class DBSimpleTable {
51
52         private final String[]  names   ;                       // データ配列に対応するカラム配列(names)
53         private String[]        keys            ;                       // 登録に使用するカラムキー配列(keys)
54         private int[]           keysNo          ;                       // 登録に使用するカラムキー配列番号
55         private String          table           ;                       // 登録テーブル名
56         private String          where           ;                       // where 条件式[カラム名]を含む
57         private int[]           whereNo         ;                       // [カラム名]に対応するデータ配列番号
58         private String[]        constrain       ;                       // key に対応した制約条件
59
60         private String          connID          ;                       // 登録に使用するコネクションID
61         private boolean         useWhere        ;                       // where が設定されると true にセットされます。
62
63         private Connection      conn            ;
64         private PreparedStatement pstmt ;
65         private ParameterMetaData pMeta ;                       // 5.1.2.0 (2010/01/01) setObject に、Type を渡す。(PostgreSQL対応)
66         private String          query           ;                       // エラーメッセージ用の変数
67         private int                     execCnt         ;
68         private ApplicationInfo appInfo ;                       // 3.8.7.0 (2006/12/15)
69         private boolean useParamMetaData;                       // 5.1.2.0 (2010/01/01) setObject に、Type を渡す。(PostgreSQL対応)
70
71         /**
72          * データ配列のカラム名称配列を指定してオブジェクトを構築します。
73          *
74          * @param       nm      カラム名称配列
75          * @throws RuntimeException tbl が null の場合
76          */
77         public DBSimpleTable( final String[] nm ) {
78                 if( nm == null ) {
79                         final String errMsg = "データ配列のカラム名称に null は設定できません。";
80                         throw new OgRuntimeException( errMsg );
81                 }
82
83                 names = new String[nm.length];
84                 System.arraycopy( nm,0,names,0,names.length );
85         }
86
87         /**
88          * 登録に使用するカラムキー配列(keys)を登録します。
89          *
90          * 引数のkey配列が null の場合は、names と同じカラム名称配列(names)が使用されます。
91          * キー配列(keys)は、一度しか登録できません。また、addConstrain等のメソッド
92          * 呼び出しを先に実行すると、カラム名称配列(names)が設定されてしまう為、
93          * その後にこのメソッドを呼び出すとエラーが発生します。
94          *
95          * @param       key     登録カラム名称配列(可変長引数)
96          * @see         #addConstrain( String ,String )
97          * @throws RuntimeException すでに キー配列(keys)が登録済み/作成済みの場合
98          */
99         public void setKeys( final String... key ) {
100                 if( keys != null ) {
101                         final String errMsg = "すでに キー配列(keys)が登録済みです。";
102                         throw new OgRuntimeException( errMsg );
103                 }
104
105                 if( key != null && key.length > 0 ) {           // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。
106                         final int size = key.length;
107                         keys = new String[size];
108                         System.arraycopy( key,0,keys,0,size );
109
110                         constrain = new String[size];
111                         Arrays.fill( constrain,"?" );
112
113                         keysNo = new int[size];
114                         for( int i=0; i<size; i++ ) {
115                                 final int address = findAddress( names,keys[i] );
116                                 if( address >= 0 ) {
117                                         keysNo[i] = address;
118                                 }
119                                 else {
120                                         final String errMsg = "指定の key は、カラム配列(names)に存在しません"
121                                                                         + " key[" + i + "]=" + key[i]
122                                                                         + " names=" + StringUtil.array2csv( names ) ;
123                                         throw new OgRuntimeException( errMsg );
124                                 }
125                         }
126                 }
127         }
128
129         /**
130          * カラム名称配列(names)と同じキー配列(keys)を作成します。
131          *
132          * これは、キー配列(keys) が作成されなかった場合の処理です。
133          * keys が null の場合のみ、処理を実行します。
134          *
135          * @see         #setKeys( String[] )
136          */
137         private void makeKeys() {
138                 // キー配列(keys) が未設定の場合は、カラム名称配列(names)が設定されます。
139                 if( keys == null ) {
140                         keys = names;
141                         final int size = keys.length;
142
143                         constrain = new String[size];
144                         Arrays.fill( constrain,"?" );
145
146                         keysNo = new int[size];
147                         for( int i=0; i<size; i++ ) {
148                                 keysNo[i] = i;
149                         }
150                 }
151         }
152
153         /**
154          * Insert/Update/Delete 時の登録するテーブル名。
155          *
156          * @param       tbl     テーブル名
157          * @throws RuntimeException tbl が null の場合
158          */
159         public void setTable( final String tbl ) {
160                 if( tbl == null ) {
161                         final String errMsg = "table に null は設定できません。";             // 5.1.8.0 (2010/07/01) errMsg 修正
162                         throw new OgRuntimeException( errMsg );
163                 }
164
165                 table = tbl;
166         }
167
168         /**
169          * データベースの接続先IDを設定します。
170          *
171          * @param       conn    接続先ID
172          */
173         public void setConnectionID( final String conn ) {
174                 connID = conn;
175         }
176
177         /**
178          * アクセスログ取得の為、ApplicationInfoオブジェクトを設定します。
179          *
180          * @og.rev 3.8.7.0 (2006/12/15) 新規追加
181          *
182          * @param   appInfo アプリ情報オブジェクト
183          */
184         public void setApplicationInfo( final ApplicationInfo appInfo ) {
185                 this.appInfo = appInfo;
186         }
187
188         /**
189          * Insert/Update/Delete 時の PreparedStatement の引数(クエスチョンマーク)制約。
190          *
191          * 制約条件(val)は、そのまま引数に使用されます。通常、? で表される
192          * パラメータに、文字長を制限する場合、SUBSTRB( ?,1,100 ) という
193          * val 変数を与えます。
194          * また、キー一つに対して、値を複数登録したい場合にも、使用できます。
195          * 例えば、NVAL( ?,? ) のような場合、キー一つに値2つを割り当てます。
196          * 値配列の並び順は、キー配列(keys)に対する(?の個数)に対応します。
197          * 注意:カラム名称配列(names)ではありません。また、先にキー配列(keys)を登録
198          * しておかないと、キー配列登録時にエラーが発生します。
199          * 制約条件は、処理するQUERYに対して適用されますので、
200          * key または、val が null の場合は、RuntimeException を Throwします。
201          *
202          * @param       key     制約をかけるキー
203          * @param       val     制約条件式
204          * @see         #setKeys( String[] )
205          * @throws RuntimeException key または、val が null の場合
206          */
207         public void addConstrain( final String key,final String val ) {
208                 if( key == null || val == null ) {
209                         final String errMsg = "key または、val に null は設定できません。"
210                                                         + " key=[" + key + "] , val=[" + val + "]" ;
211                         throw new OgRuntimeException( errMsg );
212                 }
213
214                 // キー配列(keys)が未設定(null)の場合は、カラム名称配列(names)を割り当てます。
215                 if( keys == null ) { makeKeys(); }
216
217                 // 制約条件のアドレスは、カラム名称配列(names)でなく、キー配列(keys)を使用します。
218                 final int address = findAddress( keys,key );
219                 if( address >= 0 ) {
220                         constrain[address] = val;
221                 }
222                 else {
223                         final String errMsg = "指定の key は、キー配列(keys)に存在しません"
224                                                         + " key=[" + key + "] , val=[" + val + "]"
225                                                         + " keys=" + StringUtil.array2csv( keys ) ;
226                         throw new OgRuntimeException( errMsg );
227                 }
228         }
229
230         /**
231          * Update/Delete 時のキーとなるWHERE 条件のカラム名を設定します。
232          *
233          * 通常の WHERE 句の書き方と同じで、カラム配列(names)に対応する設定値(values)の値を
234          * 割り当てたい箇所に[カラム名] を記述します。文字列の場合、設定値をセットする
235          * ときに、シングルコーテーションを使用しますが、[カラム名]で指定する場合は、
236          * その前後に、(')シングルコーテーションは、不要です。
237          * WHERE条件は、登録に使用するキー配列(keys)に現れない条件で行を特定することがありますので
238          * カラム名称配列(names)を元にカラム名のアドレスを求めます。
239          * [カラム名]は、? に置き換えて、PreparedStatement として、実行される形式に変換されます。
240          * 例:FGJ='1' and CLM=[CLM] and SYSTEM_ID in ([SYSID],'**')
241          *
242          * @og.rev 4.3.4.0 (2008/12/01) キー配列(keys)が未設定(null)の場合は、カラム名称配列(names)を割り当てる
243          * @og.rev 5.0.2.0 (2009/11/01) バグ修正(keysはデータセットのキーなので、where句のカラムに含まれて入いるわけではない)
244          * @og.rev 6.4.1.2 (2016/01/22) PMD refactoring. where は、null をセットするのではなく、useWhere の設定で判定する。
245          * @og.rev 6.4.3.4 (2016/03/11) Formatterに新しいコンストラクターを追加する。
246          * @og.rev 6.9.5.0 (2018/04/23) カラム名が存在しない場合に、Exception を throw するかどうかを指定可能にする。
247          *
248          * @param  wh WHERE条件のカラム名
249          * @throws RuntimeException [カラム名]がカラム配列(names)に存在しない場合
250          */
251         public void setWhere( final String wh ) {
252
253                 // 6.4.1.2 (2016/01/22) PMD refactoring.
254                 if( wh == null || wh.isEmpty() ) {
255                         useWhere= false;
256                 }
257                 else {
258                         // キー配列(keys)が未設定(null)の場合は、カラム名称配列(names)を割り当てます。
259                         // 5.0.2.0 (2009/11/01)
260 //                      final ArrayDataModel data = new ArrayDataModel( names );
261 //                      final ArrayDataModel data = new ArrayDataModel( names,true );           // 6.9.5.0 (2018/04/23) カラム名が存在しない場合に、Exception を throw する
262                         final DataModel<String> data = new ArrayDataModel( names,true );        // 8.2.1.0 (2022/07/15)
263                         final Formatter format = new Formatter( data,wh );                                      // 6.4.3.4 (2016/03/11)
264                         where   = format.getQueryFormatString();
265                         whereNo = format.getClmNos();
266                         useWhere= true;
267                 }
268         }
269
270         /**
271          * データをインサートする場合に使用するSQL文を作成します。
272          *
273          * @og.rev 6.2.3.0 (2015/05/01) CSV形式の作成を、String#join( CharSequence , CharSequence... )を使用。
274          *
275          * @return  インサートSQL
276          * @og.rtnNotNull
277          */
278         private String getInsertSQL() {
279                 // キー配列(keys)が未設定(null)の場合は、カラム名称配列(names)を割り当てます。
280                 if( keys == null ) { makeKeys(); }
281
282                 // 6.2.3.0 (2015/05/01) CSV形式の作成を、String#join( CharSequence , CharSequence... )を使用。
283                 final StringBuilder sql = new StringBuilder( BUFFER_MIDDLE )
284                         .append( "INSERT INTO " ).append( table )
285                         .append( " ( " )
286                         .append( String.join( "," , keys ) )                    // 6.2.3.0 (2015/05/01)
287                         .append( " ) VALUES ( " )
288                         .append( String.join( "," , constrain ) )               // 6.2.3.0 (2015/05/01)
289                         .append( " )" );
290
291                 useWhere = false;
292
293                 return sql.toString();
294         }
295
296         /**
297          * データをアップデートする場合に使用するSQL文を作成します。
298          *
299          * @og.rev 6.4.1.2 (2016/01/22) PMD refactoring. where は、null をセットするのではなく、useWhere の設定で判定する。
300          *
301          * @return  アップデートSQL
302          * @og.rtnNotNull
303          */
304         private String getUpdateSQL() {
305                 // キー配列(keys)が未設定(null)の場合は、カラム名称配列(names)を割り当てます。
306                 if( keys == null ) { makeKeys(); }
307
308                 final StringBuilder sql = new StringBuilder( BUFFER_MIDDLE )
309                         .append( "UPDATE " ).append( table ).append( " SET " )
310                         .append( keys[0] ).append( " = " ).append( constrain[0] );
311
312                 for( int i=1; i<keys.length; i++ ) {
313                         sql.append( " , " )
314                                 .append( keys[i] ).append( " = " ).append( constrain[i] );
315                 }
316
317                 // 6.4.1.2 (2016/01/22) PMD refactoring.
318                 if( useWhere ) {
319                         sql.append( " WHERE " ).append( where );
320                 }
321
322                 return sql.toString();
323         }
324
325         /**
326          * データをデリートする場合に使用するSQL文を作成します。
327          *
328          * @og.rev 5.0.2.0 (2009/11/01) バグ修正(削除時はkeysは必要ない)
329          * @og.rev 6.4.1.2 (2016/01/22) PMD refactoring. where は、null をセットするのではなく、useWhere の設定で判定する。
330          *
331          * @return  デリートSQL
332          * @og.rtnNotNull
333          */
334         private String getDeleteSQL() {
335                 // キー配列(keys)が未設定(null)の場合は、カラム名称配列(names)を割り当てます。
336                 // 5.0.2.0 (2009/11/01)
337                 keys = new String[0];
338
339                 final StringBuilder sql = new StringBuilder( BUFFER_MIDDLE )
340                         .append( "DELETE FROM " ).append( table );
341
342                 // 6.4.1.2 (2016/01/22) PMD refactoring.
343                 if( useWhere ) {
344                         sql.append( " WHERE " ).append( where );
345                 }
346
347                 return sql.toString();
348         }
349
350         /**
351          * Insert 処理の開始を宣言します。
352          * 内部的に、コネクションを接続して、PreparedStatementオブジェクトを作成します。
353          * このメソッドと、close() メソッドは必ずセットで処理してください。
354          *
355          * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為、ApplicationInfoオブジェクトを設定
356          * @og.rev 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
357          * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData を ConnectionFactory経由で取得。(PostgreSQL対応)
358          *
359          * @throws SQLException Connection のオープンに失敗した場合
360          */
361         public void startInsert() throws SQLException {
362                 execCnt = 0;
363                 query = getInsertSQL();
364                 conn  = ConnectionFactory.connection( connID,appInfo );
365                 pstmt = conn.prepareStatement( query );
366                 // 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
367                 useParamMetaData = ConnectionFactory.useParameterMetaData( connID );    // 5.3.8.0 (2011/08/01)
368                 if( useParamMetaData ) {
369                         pMeta = pstmt.getParameterMetaData();
370                 }
371         }
372
373         /**
374          * Update 処理の開始を宣言します。
375          * 内部的に、コネクションを接続して、PreparedStatementオブジェクトを作成します。
376          * このメソッドと、close() メソッドは必ずセットで処理してください。
377          *
378          * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為、ApplicationInfoオブジェクトを設定
379          * @og.rev 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
380          * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData を ConnectionFactory経由で取得。(PostgreSQL対応)
381          *
382          * @throws SQLException Connection のオープンに失敗した場合
383          */
384         public void startUpdate() throws SQLException {
385                 execCnt = 0;
386                 query = getUpdateSQL();
387                 conn  = ConnectionFactory.connection( connID,appInfo );
388                 pstmt = conn.prepareStatement( query );
389                 // 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
390                 useParamMetaData = ConnectionFactory.useParameterMetaData( connID );    // 5.3.8.0 (2011/08/01)
391                 if( useParamMetaData ) {
392                         pMeta = pstmt.getParameterMetaData();
393                 }
394         }
395
396         /**
397          * Delete 処理の開始を宣言します。
398          * 内部的に、コネクションを接続して、PreparedStatementオブジェクトを作成します。
399          * このメソッドと、close() メソッドは必ずセットで処理してください。
400          *
401          * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為、ApplicationInfoオブジェクトを設定
402          * @og.rev 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
403          * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData を ConnectionFactory経由で取得。(PostgreSQL対応)
404          *
405          * @throws SQLException Connection のオープンに失敗した場合
406          */
407         public void startDelete() throws SQLException {
408                 execCnt = 0;
409                 query = getDeleteSQL();
410                 conn  = ConnectionFactory.connection( connID,appInfo );
411                 pstmt = conn.prepareStatement( query );
412                 // 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
413                 useParamMetaData = ConnectionFactory.useParameterMetaData( connID );    // 5.3.8.0 (2011/08/01)
414                 if( useParamMetaData ) {
415                         pMeta = pstmt.getParameterMetaData();
416                 }
417         }
418
419         /**
420          * データ配列を渡して実際のDB処理を実行します。
421          *
422          * この処理の前に、startXXXX をコールしておき、INSER,UPDATE,DELETEのどの
423          * 処理を行うか、宣言しておく必要があります。
424          * 戻り値は、この処理での処理件数です。
425          * 最終件数は、close( boolean ) 時に取得します。
426          *
427          * @og.rev 4.0.0.0 (2007/11/28) SQLException をきちんと伝播させます。
428          * @og.rev 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
429          * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData 時の setNull 対応(PostgreSQL対応)
430          *
431          * @param       values  カラム配列(names)に対応する設定値配列(可変長引数)
432          *
433          * @return      ここでの処理件数
434          *
435          * @see    #close( boolean )
436          * @throws SQLException Connection のクロースに失敗した場合
437          * @throws RuntimeException Connection DB処理の実行に失敗した場合
438          */
439         public int execute( final String... values ) throws SQLException {
440                 final int cnt;
441                 try {
442                         int clmNo = 1;  // JDBC のカラム番号は、1から始まる。
443
444                         // 5.1.2.0 (2010/01/01) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応)
445                         if( useParamMetaData ) {
446                                 // keys に値を割り当てます。
447                                 for( int i=0; i<keys.length; i++ ) {
448                                         final int type = pMeta.getParameterType( clmNo );
449                                         // 5.3.8.0 (2011/08/01) setNull 対応
450                                         final String val = values[keysNo[i]];
451                                         if( val == null || val.isEmpty() ) {
452                                                 pstmt.setNull( clmNo++, type );
453                                         }
454                                         else {
455                                                 pstmt.setObject( clmNo++,val,type );
456                                         }
457                                 }
458
459                                 // where 条件を使用する場合は、値を割り当てます。
460                                 if( useWhere ) {
461                                         for( int i=0; i<whereNo.length; i++ ) {
462                                                 final int type = pMeta.getParameterType( clmNo );
463                                                 // 5.3.8.0 (2011/08/01) setNull 対応
464                                                 final String val = values[whereNo[i]];
465                                                 if( val == null || val.isEmpty() ) {
466                                                         pstmt.setNull( clmNo++, type );
467                                                 }
468                                                 else {
469                                                         pstmt.setObject( clmNo++,val,type );
470                                                 }
471                                         }
472                                 }
473                         }
474                         else {
475                                 // keys に値を割り当てます。
476                                 for( int i=0; i<keys.length; i++ ) {
477                                         pstmt.setObject( clmNo++,values[keysNo[i]] );
478                                 }
479
480                                 // where 条件を使用する場合は、値を割り当てます。
481                                 if( useWhere ) {
482                                         for( int i=0; i<whereNo.length; i++ ) {
483                                                 pstmt.setObject( clmNo++,values[whereNo[i]] );
484                                         }
485                                 }
486                         }
487
488                         cnt = pstmt.executeUpdate();
489                         execCnt += cnt;
490                 }
491                 catch( final SQLException ex) {
492                         Closer.stmtClose( pstmt );
493                         pMeta = null;           // 5.1.2.0 (2010/01/01)
494                         if( conn != null ) {
495                                 conn.rollback();
496                                 ConnectionFactory.remove( conn,connID );
497                                 conn = null;
498                         }
499                         final String errMsg = "DB処理の実行に失敗しました。" + CR
500                                                         + " query=[" + query + "]" + CR
501                                                         + " values=" + StringUtil.array2csv( values );
502                         throw new OgRuntimeException( errMsg ,ex );
503                 }
504                 return cnt;
505         }
506
507         /**
508          * DB処理をクロースします。
509          *
510          * 引数には、commit させる場合は、true を、rollback させる場合は、false をセットします。
511          * 戻り値は、今まで処理された合計データ件数です。
512          * この処理は、SQLException を内部で RuntimeException に変換している為、catch 節は
513          * 不要ですが、必ず finally 節で呼び出してください。そうしないと、リソースリークの
514          * 原因になります。
515          *
516          * @og.rev 5.1.2.0 (2010/01/01) pMeta のクリア
517          *
518          * @param  commitFlag コミットフラグ [true:commitする/false:rollbacする]
519          *
520          * @return      今までの合計処理件数
521          */
522         public int close( final boolean commitFlag ) {
523                 try {
524 //                      if( conn != null ) {                                                                                            // 8.1.1.2 (2022/02/25) Modify
525                         if( conn != null && !conn.isClosed() ) {
526                                 if( commitFlag ) {      conn.commit();  }
527                                 else {                          conn.rollback(); }
528                         }
529                 }
530                 catch( final SQLException ex) {
531                         ConnectionFactory.remove( conn,connID );
532                         conn = null;
533                         final String errMsg = "DB処理を確定(COMMIT)できませんでした。" + CR
534                                                         + " query=[" + query + "]" + CR ;
535                         throw new OgRuntimeException( errMsg,ex );
536                 }
537                 finally {
538                         Closer.stmtClose( pstmt );
539                         pMeta = null;           // 5.1.2.0 (2010/01/01)
540                         ConnectionFactory.close( conn,connID );
541                         conn = null;
542                 }
543
544                 return execCnt;
545         }
546
547         /**
548          * 文字列配列中の値とマッチするアドレスを検索します。
549          * 文字列配列がソートされていない為、バイナリサーチが使えません。よって、
550          * 総当りでループ検索しています。
551          * 総数が多い場合は、遅くなる為、マップにセットして使用することを検討ください。
552          *
553          * @param       data    ターゲットの文字列配列中
554          * @param       key     検索する文字列
555          *
556          * @return  ターゲットの添え字(存在しない場合は、-1)
557          */
558         private int findAddress( final String[] data,final String key ) {
559                 int address = -1;
560                 if( data != null && key != null ) {
561                         for( int i=0; i<data.length; i++ ) {
562                                 if( key.equalsIgnoreCase( data[i] ) ) {
563                                         address = i;
564                                         break;
565                                 }
566                         }
567                 }
568                 return address;
569         }
570 }