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.process; 017 018import java.sql.Connection; 019import java.sql.ResultSet; 020import java.sql.PreparedStatement; 021import java.sql.SQLException; 022import java.io.File ; 023import java.io.PrintWriter ; 024import java.util.Map ; 025import java.util.LinkedHashMap ; 026import java.util.Calendar ; 027 028import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 029import org.opengion.fukurou.system.LogWriter; 030import org.opengion.fukurou.system.Closer; 031import org.opengion.fukurou.model.Formatter; 032import org.opengion.fukurou.util.Argument; 033import org.opengion.fukurou.util.SystemParameter; 034import org.opengion.fukurou.util.FileUtil; 035import org.opengion.fukurou.util.HybsDateUtil; 036import org.opengion.fukurou.util.HybsEntry ; 037import org.opengion.fukurou.db.DBUtil ; 038import org.opengion.fukurou.db.ConnectionFactory; 039 040/** 041 * Process_DBFileout は、SELECT文 を指定し データベースの値を抜き出して、 042 * 個々のファイルにセーブする、ChainProcess インターフェースの実装クラスです。 043 * 上流(プロセスチェインのデータは上流から下流へと渡されます。)から 044 * 受け取った LineModel を元に、1行単位に、SELECT文を実行します。 045 * 046 * 上流のカラムを、[カラム]変数で使用できます。 047 * また、セーブするファイル名、更新日付等も、都度、更新可能です。 048 * 049 * データベース接続先等は、ParamProcess のサブクラス(Process_DBParam)に 050 * 設定された接続(Connection)を使用します。 051 * 052 * 引数文字列中にスペースを含む場合は、ダブルコーテーション("") で括って下さい。 053 * 引数文字列の 『=』 の前後には、スペースは挟めません。必ず、-key=value の様に 054 * 繋げてください。 055 * 056 * SQL文には、{@DATE.YMDH}等のシステム変数が使用できます。 057 * 058 * @og.formSample 059 * Process_DBFileout -dbid=DBGE -insertTable=GE41 060 * 061 * [ -dbid=DB接続ID ] : -dbid=DBGE (例: Process_DBParam の -configFile で指定する DBConfig.xml ファイルで規定) 062 * [ -select=検索SQL文 ] : -select="SELECT * FROM GE41 WHERE SYSTEM_ID = [SYSTEM_ID] AND CLM = [CLM]" 063 * [ -selectFile=登録SQLファイル ] : -selectFile=select.sql 064 * : -select や -selectFile が指定されない場合は、エラーです。 065 * [ -select_XXXX=固定値 ] : -select_SYSTEM_ID=GE 066 * SQL文中の{@XXXX}文字列を指定の固定値で置き換えます。 067 * WHERE SYSTEM_ID='{@SYSTEM_ID}' ⇒ WHERE SYSTEM_ID='GE' 068 * [ -const_XXXX=固定値 ] : -const_FGJ=1 069 * LineModel のキー(const_ に続く文字列)の値に、固定値を設定します。 070 * キーが異なれば、複数のカラム名を指定できます。 071 * [ -addHeader=ヘッダー ] : -addHeader="CREATE OR REPLACE " 072 * [ -addFooter=フッター ] : -addFooter="/\nSHOW ERROR;" 073 * [ -outFile=出力ファイル名 ] : -outFile=[NAME].sql 074 * [ -append=[false/true] ] : 出力ファイルを、追記する(true)か新規作成する(false)か。 075 * [ -sep=セパレータ文字 ] : 各カラムを区切る文字列(初期値:TAB) 076 * [ -useLineCR=[false/true] ] : 各行の最後に、改行文字をつかるかどうか(初期値:true[付ける]) 077 * [ -timestamp=更新日付 ] : -timestamp="LAST_DDL_TIME" 078 * [ -fetchSize=1000 ] :フェッチする行数(初期値:1000) 6.9.4.1 (2018/04/09) 079 * [ -display=[false/true] ] : 結果を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない]) 080 * [ -debug=[false/true] ] : デバッグ情報を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない]) 081 * 082 * @og.rev 6.4.8.3 (2016/07/15) 新規作成。 083 * 084 * @version 4.0 085 * @author Kazuhiko Hasegawa 086 * @since JDK5.0, 087 */ 088public class Process_DBFileout extends AbstractProcess implements ChainProcess { 089 private static final String SELECT_KEY = "select_" ; 090 private static final String CNST_KEY = "const_" ; 091 092 private static final String ENCODE = "UTF-8" ; 093 094// /** 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズ {@value} */ 095// private static final int DB_FETCH_SIZE = 1001 ; 096 097 private Connection connection ; 098 private PreparedStatement selPstmt ; 099 100 private String dbid ; 101 private String select ; 102 private int[] selClmNos ; // select 時のファイルのヘッダーのカラム番号 103 private String outFilename ; // 出力ファイル名 104 private boolean append ; // ファイル追加(true:追加/false:通常) 105 private String timestamp ; // 出力ファイルの更新日時 106 private int tmstmpClm = -1; // 出力ファイルの更新日時のカラム番号 107 private String separator = "\t"; // 各カラムを区切る文字列(初期値:TAB) 108 private String addHeader ; // ヘッダー 109 private String addFooter ; // フッター 110 private boolean useLineCR = true; // 各行の最後に、改行文字をつかるかどうか(初期値:true[付ける]) 111 private int fetchSize = 1000; // 6.9.4.1 (2018/04/09) 初期値を 1000 に設定 112 private boolean display ; // false:表示しない 113 private boolean debug ; // 5.7.3.0 (2014/02/07) デバッグ情報 114 115 private String[] cnstClm ; // 固定値を設定するカラム名 116 private int[] cnstClmNos ; // 固定値を設定するカラム番号 117 private String[] constVal ; // カラム番号に対応した固定値 118 119 private boolean firstRow = true; // 最初の一行目 120 private int count ; 121 122 /** staticイニシャライザ後、読み取り専用にするので、ConcurrentHashMap を使用しません。 */ 123 private static final Map<String,String> MUST_PROPARTY ; // [プロパティ]必須チェック用 Map 124 /** staticイニシャライザ後、読み取り専用にするので、ConcurrentHashMap を使用しません。 */ 125 private static final Map<String,String> USABLE_PROPARTY ; // [プロパティ]整合性チェック Map 126 127 static { 128 MUST_PROPARTY = new LinkedHashMap<>(); 129 130 USABLE_PROPARTY = new LinkedHashMap<>(); 131 USABLE_PROPARTY.put( "dbid", "Process_DBParam の -configFile で指定する DBConfig.xml ファイルで規定" ); 132 USABLE_PROPARTY.put( "select", "検索SQL文(select or selectFile 必須)" + 133 CR + "例: \"SELECT * FROM GE41 WHERE SYSTEM_ID = [SYSTEM_ID] AND CLM = [CLM]\"" ); 134 USABLE_PROPARTY.put( "selectFile", "検索SQLファイル(select or selectFile 必須)例: select.sql" ); 135 USABLE_PROPARTY.put( "select_", "SQL文中の{@XXXX}文字列を指定の固定値で置き換えます。" + 136 CR + "WHERE SYSTEM_ID='{@SYSTEM_ID}' ⇒ WHERE SYSTEM_ID='GE'" ); 137 USABLE_PROPARTY.put( "const_", "LineModel のキー(const_ に続く文字列)の値に、固定値を" + 138 CR + "設定します。キーが異なれば、複数のカラム名を指定できます。" + 139 CR + "例: -sql_SYSTEM_ID=GE" ); 140 USABLE_PROPARTY.put( "addHeader" , "ヘッダー" ); 141 USABLE_PROPARTY.put( "addFooter" , "フッター" ); 142 USABLE_PROPARTY.put( "outFile" , "出力ファイル名 例: [NAME].sql" ); 143 USABLE_PROPARTY.put( "append" , "出力ファイルを、追記する(true)か新規作成する(false)か。" ); 144 USABLE_PROPARTY.put( "sep" , "各カラムを区切る文字列(初期値:TAB)" ); 145 USABLE_PROPARTY.put( "useLineCR", "各行の最後に、改行文字をつかるかどうか(初期値:true[付ける])" ); 146 USABLE_PROPARTY.put( "timestamp", "出力ファイルの更新日付例: [LAST_DDL_TIME]" ); 147 USABLE_PROPARTY.put( "fetchSize","フェッチする行数 (初期値:1000)" ); // 6.9.4.1 (2018/04/09) 初期値を 1000 に設定 148 USABLE_PROPARTY.put( "display", "結果を標準出力に表示する(true)かしない(false)か" + 149 CR + "(初期値:false:表示しない)" ); 150 USABLE_PROPARTY.put( "debug", "デバッグ情報を標準出力に表示する(true)かしない(false)か" + 151 CR + "(初期値:false:表示しない)" ); // 5.7.3.0 (2014/02/07) デバッグ情報 152 } 153 154 /** 155 * デフォルトコンストラクター。 156 * このクラスは、動的作成されます。デフォルトコンストラクターで、 157 * super クラスに対して、必要な初期化を行っておきます。 158 * 159 */ 160 public Process_DBFileout() { 161 super( "org.opengion.fukurou.process.Process_DBFileout",MUST_PROPARTY,USABLE_PROPARTY ); 162 } 163 164 /** 165 * プロセスの初期化を行います。初めに一度だけ、呼び出されます。 166 * 初期処理(ファイルオープン、DBオープン等)に使用します。 167 * 168 * @og.rev 6.4.8.3 (2016/07/15) 新規作成。 169 * @og.rev 6.9.4.1 (2018/04/09) fetchSize 指定を行います。 170 * 171 * @param paramProcess データベースの接続先情報などを持っているオブジェクト 172 */ 173 public void init( final ParamProcess paramProcess ) { 174 final Argument arg = getArgument(); 175 176 select = arg.getFileProparty( "select","selectFile",false ); 177 separator = arg.getProparty( "sep" , separator ); 178 outFilename = arg.getProparty( "outFile" , outFilename ); 179 append = arg.getProparty( "append" , append ); 180 addHeader = arg.getProparty( "addHeader" , addHeader ); 181 addFooter = arg.getProparty( "addFooter" , addFooter ); 182 useLineCR = arg.getProparty( "useLineCR" , useLineCR ); 183 timestamp = arg.getProparty( "timestamp" , timestamp ); 184 fetchSize = arg.getProparty( "fetchSize" , fetchSize ); // 6.9.4.1 (2018/04/09) fetchSize 指定 185 display = arg.getProparty( "display" , display ); 186 debug = arg.getProparty( "debug" , debug ); 187 188 addHeader = addHeader.replaceAll( "\\\\t" , "\t" ).replaceAll( "\\\\n" , "\n" ); // 「\t」と、「\n」の文字列を、タブと改行に変換します。 189 addFooter = addFooter.replaceAll( "\\\\t" , "\t" ).replaceAll( "\\\\n" , "\n" ); // 「\t」と、「\n」の文字列を、タブと改行に変換します。 190 191 dbid = arg.getProparty( "dbid" ); 192 connection = paramProcess.getConnection( dbid ); 193 194 if( select == null ) { 195 final String errMsg = "select または、selectFile は必ず指定してください。"; 196 throw new OgRuntimeException( errMsg ); 197 } 198 199 // 3.8.0.1 (2005/06/17) {@DATE.XXXX} 変換処理の追加 200 // {@DATE.YMDH} などの文字列を、yyyyMMddHHmmss 型の日付に置き換えます。 201 // SQL文の {@XXXX} 文字列の固定値への置き換え 202 final HybsEntry[] entry =arg.getEntrys(SELECT_KEY); // 配列 203 final SystemParameter sysParam = new SystemParameter( select ); 204 select = sysParam.replace( entry ); 205 206 final HybsEntry[] cnstKey = arg.getEntrys( CNST_KEY ); // 配列 207 final int csize = cnstKey.length; 208 cnstClm = new String[csize]; 209 constVal = new String[csize]; 210 for( int i=0; i<csize; i++ ) { 211 cnstClm[i] = cnstKey[i].getKey(); 212 constVal[i] = cnstKey[i].getValue(); 213 } 214 } 215 216 /** 217 * プロセスの終了を行います。最後に一度だけ、呼び出されます。 218 * 終了処理(ファイルクローズ、DBクローズ等)に使用します。 219 * 220 * @og.rev 6.4.8.3 (2016/07/15) 新規作成。 221 * 222 * @param isOK トータルで、OKだったかどうか[true:成功/false:失敗] 223 */ 224 public void end( final boolean isOK ) { 225 final boolean flag1 = Closer.stmtClose( selPstmt ); 226 selPstmt = null; 227 228 // close に失敗しているのに commit しても良いのか? 229 if( isOK ) { 230 Closer.commit( connection ); 231 } 232 else { 233 Closer.rollback( connection ); 234 } 235 ConnectionFactory.remove( connection,dbid ); 236 237 if( ! flag1 ) { 238 final String errMsg = "select ステートメントをクローズ出来ません。" + CR 239 + " select=[" + select + "] , commit=[" + isOK + "]" ; 240 System.err.println( errMsg ); 241 } 242 } 243 244 /** 245 * 引数の LineModel を処理するメソッドです。 246 * 変換処理後の LineModel を返します。 247 * 後続処理を行わない場合(データのフィルタリングを行う場合)は、 248 * null データを返します。つまり、null データは、後続処理を行わない 249 * フラグの代わりにも使用しています。 250 * なお、変換処理後の LineModel と、オリジナルの LineModel が、 251 * 同一か、コピー(クローン)かは、各処理メソッド内で決めています。 252 * ドキュメントに明記されていない場合は、副作用が問題になる場合は、 253 * 各処理ごとに自分でコピー(クローン)して下さい。 254 * 255 * @og.rev 6.4.8.3 (2016/07/15) 新規作成。 256 * @og.rev 6.9.4.1 (2018/04/09) fetchSize 指定を行います。 257 * @og.rev 6.9.8.0 (2018/05/28) FindBugs:例外的戻り値を無視しているメソッド(mkdirs) 258 * @og.rev 8.5.4.2 (2024/01/12) PMD 7.0.0 ExceptionAsFlowControl 対応 259 * 260 * @param data オリジナルのLineModel 261 * 262 * @return 処理変換後のLineModel 263 */ 264 @Override // ChainProcess 265 public LineModel action( final LineModel data ) { 266 count++ ; 267// try { 268 if( firstRow ) { 269 makePrepareStatement( data ); 270 271 final int size = cnstClm.length; 272 cnstClmNos = new int[size]; 273 for( int i=0; i<size; i++ ) { 274 cnstClmNos[i] = data.getColumnNo( cnstClm[i] ); 275 } 276 277 if( display ) { println( data.nameLine() ); } // 5.7.3.0 (2014/02/07) デバッグ情報 278 279 if( timestamp != null ) { 280 tmstmpClm = data.getColumnNo( timestamp ); 281 } 282 firstRow = false; 283 } 284 285 // 固定値置き換え処理 286 for( int j=0; j<cnstClmNos.length; j++ ) { 287 data.setValue( cnstClmNos[j],constVal[j] ); 288 } 289 290 // 8.5.4.2 (2024/01/12) PMD 7.0.0 ExceptionAsFlowControl 対応 291 final String[][] rtn ; 292 try { 293 if( selClmNos != null ) { 294 for( int i=0; i<selClmNos.length; i++ ) { 295 selPstmt.setObject( i+1,data.getValue(selClmNos[i]) ); 296 } 297 } 298 299// final Formatter fileFmt = new Formatter( data,outFilename ); 300// final File outFile = new File( fileFmt.getFormatString(0) ); 301// // 6.9.8.0 (2018/05/28) FindBugs:例外的戻り値を無視しているメソッド 302//// if( !outFile.getParentFile().exists() ) { 303//// outFile.getParentFile().mkdirs(); 304//// } 305// final File parent = outFile.getParentFile(); // 親フォルダを取得。nullもありえる 306// if( parent == null || !parent.exists() && !parent.mkdirs() ) { 307// final String errMsg = "親フォルダを作成できませんでした。[" + data.getRowNo() + "]件目" + CR 308// + " outFile=[" + fileFmt.getFormatString(0) + "]" + CR ; 309// throw new OgRuntimeException( errMsg ); 310// } 311 312// final String[][] rtn ; 313 try( ResultSet resultSet = selPstmt.executeQuery() ) { 314 rtn = DBUtil.resultToArray( resultSet,false ); // useHeader = false 315 } 316 } 317 // 8.5.4.2 (2024/01/12) PMD 7.0.0 ExceptionAsFlowControl 対応 318 catch( final SQLException ex) { 319 final String errMsg = "検索処理でエラーが発生しました。[" + data.getRowNo() + "]件目" + CR 320 + " select=[" + select + "]" + CR 321 + " errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 322 + " data=[" + data.dataLine() + "]" + CR ; 323 throw new OgRuntimeException( errMsg,ex ); 324 } 325 326 final Formatter fileFmt = new Formatter( data,outFilename ); 327 final File outFile = new File( fileFmt.getFormatString(0) ); 328 // 6.9.8.0 (2018/05/28) FindBugs:例外的戻り値を無視しているメソッド 329// if( !outFile.getParentFile().exists() ) { 330// outFile.getParentFile().mkdirs(); 331// } 332 final File parent = outFile.getParentFile(); // 親フォルダを取得。nullもありえる 333 if( parent == null || !parent.exists() && !parent.mkdirs() ) { 334 final String errMsg = "親フォルダを作成できませんでした。[" + data.getRowNo() + "]件目" + CR 335 + " outFile=[" + fileFmt.getFormatString(0) + "]" + CR ; 336 throw new OgRuntimeException( errMsg ); 337 } 338 339 // 0件の場合は、ヘッダーもフッターも出力しません。 340 if( rtn.length > 0 ) { 341 try( PrintWriter writer = FileUtil.getPrintWriter( outFile,ENCODE,append ) ) { 342 if( addHeader != null ) { 343 final Formatter headerFmt = new Formatter( data,addHeader ); 344 final String header = headerFmt.getFormatString(0); 345 writer.print( header ); 346 } 347 // 8.5.4.2 (2024/01/12) PMD 7.0.0 ForLoopCanBeForeach 348// for( int i=0; i<rtn.length; i++ ) { 349// for( int j=0; j<rtn[i].length; j++ ) { 350// writer.print( rtn[i][j] ); 351// writer.print( separator ); 352// } 353// if( useLineCR ) { writer.println(); } 354// } 355 for( final String[] row : rtn ) { 356 for( final String clm : row ) { 357 writer.print( clm ); 358 writer.print( separator ); 359 } 360 if( useLineCR ) { writer.println(); } 361 } 362 if( addFooter != null ) { 363 final Formatter footerFmt = new Formatter( data,addFooter ); 364 final String footer = footerFmt.getFormatString(0); 365 writer.print( footer ); 366 } 367 } 368 } 369 370 if( tmstmpClm >= 0 ) { 371 final String tmStmp = String.valueOf( data.getValue( tmstmpClm ) ); 372 final Calendar cal = HybsDateUtil.getCalendar( tmStmp ); 373 // 6.9.8.0 (2018/05/28) FindBugs:例外的戻り値を無視しているメソッド 374// outFile.setLastModified( cal.getTimeInMillis() ); 375 if( !outFile.setLastModified( cal.getTimeInMillis() ) ) { 376 final String errMsg = "タイムスタンプの更新が出来ませんでした。[" + data.getRowNo() + "]件目" + CR 377 + " outFile= [" + outFile + "]" + CR ; 378 System.err.println( errMsg ); 379 } 380 } 381 382 if( display ) { println( data.dataLine() ); } 383// } 384// catch( final SQLException ex) { 385// final String errMsg = "検索処理でエラーが発生しました。[" + data.getRowNo() + "]件目" + CR 386// + " select=[" + select + "]" + CR 387// + " errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 388// + " data=[" + data.dataLine() + "]" + CR ; 389// throw new OgRuntimeException( errMsg,ex ); 390// } 391 return data; 392 } 393 394 /** 395 * 内部で使用する PreparedStatement を作成します。 396 * 引数指定の SQL または、LineModel から作成した SQL より構築します。 397 * 398 * @og.rev 6.4.8.3 (2016/07/15) 新規作成。 399 * @og.rev 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズを設定。 400 * @og.rev 6.9.4.1 (2018/04/09) fetchSize 指定を行います。 401 * 402 * @param data 処理対象のLineModel 403 */ 404 private void makePrepareStatement( final LineModel data ) { 405 406 final Formatter format = new Formatter( data,select ); // 6.4.3.4 (2016/03/11) 407 select = format.getQueryFormatString(); 408 selClmNos = format.getClmNos(); 409 410 for( int i=0; i<selClmNos.length; i++ ) { 411 // 指定のカラムが存在しない場合は、エラーにします。 412 if( selClmNos[i] < 0 ) { 413 final String errMsg = "フォーマットに対応したカラムが存在しません。" + CR 414 + "select=[" + select + "]" + CR 415 + "ClmKey=[" + format.getClmKeys()[i] + "]" + CR 416 + "nameLine=[" + data.nameLine() + "]" + CR 417 + "data=[" + data.dataLine() + "]" + CR ; 418 throw new OgRuntimeException( errMsg ); 419 } 420 } 421 422 try { 423 selPstmt = connection.prepareStatement( select ); 424// selPstmt.setFetchSize( DB_FETCH_SIZE ); // 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズ 425 selPstmt.setFetchSize( fetchSize ); // 6.9.4.1 (2018/04/09) fetchSize 指定 426 } 427 catch( final SQLException ex) { 428 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 429 final String errMsg = "PreparedStatement を取得できませんでした。" + CR 430 + "errMsg=[" + ex.getMessage() + "]" + CR 431 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 432 + "select=[" + select + "]" + CR 433 + "nameLine=[" + data.nameLine() + "]" + CR 434 + "data=[" + data.dataLine() + "]" + CR ; 435 throw new OgRuntimeException( errMsg,ex ); 436 } 437 } 438 439 /** 440 * プロセスの処理結果のレポート表現を返します。 441 * 処理プログラム名、入力件数、出力件数などの情報です。 442 * この文字列をそのまま、標準出力に出すことで、結果レポートと出来るような 443 * 形式で出してください。 444 * 445 * @return 処理結果のレポート 446 */ 447 public String report() { 448 // 7.2.9.5 (2020/11/28) PMD:Consider simply returning the value vs storing it in local variable 'XXXX' 449 return "[" + getClass().getName() + "]" + CR 450// final String report = "[" + getClass().getName() + "]" + CR 451 + TAB + "DBID : " + dbid + CR 452 + TAB + "Input Count : " + count ; 453 454// return report ; 455 } 456 457 /** 458 * このクラスの使用方法を返します。 459 * 460 * @return このクラスの使用方法 461 * @og.rtnNotNull 462 */ 463 public String usage() { 464 final StringBuilder buf = new StringBuilder( BUFFER_LARGE ) 465 .append( "Process_DBFileout は、SELECT文 を指定し データベースの値を抜き出して、" ).append( CR ) 466 .append( "個々のファイルにセーブする、ChainProcess インターフェースの実装クラスです。" ).append( CR ) 467 .append( "上流(プロセスチェインのデータは上流から下流へと渡されます。)から" ).append( CR ) 468 .append( "受け取った LineModel を元に、1行単位に、SELECT文を実行します。" ).append( CR ) 469 .append( CR ) 470 .append( "上流のカラムを、[カラム]変数で使用できます。" ).append( CR ) 471 .append( "また、セーブするファイル名、更新日付等も、都度、更新可能です。" ).append( CR ) 472 .append( CR ) 473// .append( "データベース接続先等は、ParamProcess のサブクラス(Process_DBParam)に" ).append( CR ) 474// .append( "設定された接続(Connection)を使用します。" ).append( CR ) 475// .append( CR ) 476// .append( "SQL文には、{@DATE.YMDH}等のシステム変数が使用できます。" ).append( CR ) 477 .append( DB_PARAM_USAGE ) // 8.5.6.1 (2024/03/29) 継承元使用 478 .append( CR ) 479// .append( "引数文字列中にスペースを含む場合は、ダブルコーテーション(\"\") で括って下さい。").append( CR ) 480// .append( "引数文字列の 『=』 の前後には、スペースは挟めません。必ず、-key=value の様に" ).append( CR ) 481// .append( "繋げてください。" ).append( CR ) 482 .append( PROCESS_PARAM_USAGE ) // 8.5.6.1 (2024/03/29) 継承元使用 483 .append( CR ).append( CR ) 484 .append( getArgument().usage() ).append( CR ); 485 486 return buf.toString(); 487 } 488 489 /** 490 * このクラスは、main メソッドから実行できません。 491 * 492 * @param args コマンド引数配列 493 */ 494 public static void main( final String[] args ) { 495 LogWriter.log( new Process_DBFileout().usage() ); 496 } 497}