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 org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 019import org.opengion.fukurou.util.Argument; 020import org.opengion.fukurou.util.SystemParameter; 021import org.opengion.fukurou.util.StringUtil; 022import org.opengion.fukurou.system.LogWriter; 023import org.opengion.fukurou.util.HybsEntry ; 024import org.opengion.fukurou.system.Closer; 025import org.opengion.fukurou.model.Formatter; 026import org.opengion.fukurou.db.ConnectionFactory; 027 028import java.util.Map ; 029import java.util.LinkedHashMap ; 030import java.util.Set ; 031import java.util.HashSet ; 032 033import java.sql.Connection; 034import java.sql.Statement; 035import java.sql.PreparedStatement; 036import java.sql.ParameterMetaData; 037import java.sql.SQLException; 038 039/** 040 * Process_DBWriter は、上流から受け取ったデータをデータベースに書き込む 041 * CainProcess インターフェースの実装クラスです。 042 * 043 * 上流(プロセスチェインのデータは上流から下流へと渡されます。)から受け取った 044 * LineModel を元に、データベースへの書き込みを行います。 045 * 046 * データベース接続先等は、ParamProcess のサブクラス(Process_DBParam)に 047 * 設定された接続(Connection)を使用します。 048 * 049 * 引数文字列中にスペースを含む場合は、ダブルコーテーション("") で括って下さい。 050 * 引数文字列の 『=』の前後には、スペースは挟めません。必ず、-key=value の様に 051 * 繋げてください。 052 * 053 * SQL文には、{@DATE.YMDH}等のシステム変数が使用できます。 054 * 055 * @og.formSample 056 * Process_DBWriter -dbid=DBGE -table=GE41 057 * 058 * [ -dbid=DB接続ID ] : -dbid=DBGE (例: Process_DBParam の -configFile で指定する DBConfig.xml ファイルで規定) 059 * [ -table=登録テーブルID ] : SQL文を指定する場合は不要。INSERT する場合のテーブルID 060 * [ -sql=検索SQL文 ] : -sql="UPDATE GE41 SET NAME_JA = [NAME_JA],LABEL_NAME = [LABEL_NAME] 061 * WHERE SYSTEM_ID = [SYSTEM_ID] AND CLM = [CLM]" 062 * [ -sqlFile=登録SQLファイル ] : -sqlFile=update.sql 063 * : -sql や -sqlFile が指定されない場合は、-table で指定のテーブルに全カラム insert です。 064 * [ -sql_XXXX=固定値 ] : -sql_SYSTEM_ID=GE 065 * SQL文中の{@XXXX}文字列を指定の固定値で置き換えます。 066 * WHERE SYSTEM_ID='{@SYSTEM_ID}' ⇒ WHERE SYSTEM_ID='GE' 067 * [ -const_XXXX=固定値 ] : -const_FGJ=1 068 * LineModel のキー(const_ に続く文字列)の値に、固定値を設定します。 069 * キーが異なれば、複数のカラム名を指定できます。 070 * [ -omitClms=AAA,BBB,… ] : -omitClms=UNIQ,FGJ,DYSET 071 * -table 属性でINSERT文を自動作成する場合、取り除くカラム名を 072 * CSV形式で複数指定できます。 073 * [ -initSql=開始時SQL文 ] : -initSql="DELETE FROM GE41 WHERE FGJ = '9'" 074 * [ -initSqlFile=開始時SQLファイル] : -initSqlFile=update.sql 075 * [ -endSql=終了時SQL文 ] : -endSql="UPDATE GE41 SET FGJ = '1'" 076 * [ -endSqlFile=終了時SQLファイル ] : -endSqlFile=update.sql 077 * [ -commitCnt=commit処理指定 ] : 指定数毎にコミットを発行します。0 の場合は、終了までコミットしません。 078 * [ -display=[false/true] ] : 結果を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない]) 079 * [ -debug=[false/true] ] :デバッグ情報を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない]) 080 * 081 * @version 4.0 082 * @author Kazuhiko Hasegawa 083 * @since JDK5.0, 084 */ 085public class Process_DBWriter extends AbstractProcess implements ChainProcess { 086 private static final String CNST_KEY = "const_" ; 087 private static final String SQL_KEY = "sql_" ; 088 089 private Connection connection ; 090 private PreparedStatement pstmt ; 091 private ParameterMetaData pMeta ; // 5.1.1.0 (2009/11/11) setObject に、Type を渡す。(PostgreSQL対応) 092 private boolean useParamMetaData; // 5.1.1.0 (2009/11/11) setObject に、Type を渡す。(PostgreSQL対応) 093 094 private String dbid ; 095 private String sql ; 096 private String endSql ; // 5.7.2.2 (2014/01/24) 追加 097 private String table ; 098 private int[] clmNos ; // ファイルのヘッダーのカラム番号 099 private int commitCnt ; // コミットするまとめ件数 100 private boolean display ; // false:表示しない 101 private boolean debug ; // 5.7.3.0 (2014/02/07) デバッグ情報 102 103 private String[] cnstClm ; // 固定値を設定するカラム名 104 private int[] cnstClmNos ; // 固定値を設定するカラム番号 105 private String[] constVal ; // カラム番号に対応した固定値 106 107 private boolean firstRow = true; // 最初の一行目 108 private int count ; 109 private String[] omitClms ; // 4.0.0.0 (2007/09/21) table 指定時に取り除くカラム 110 111 /** staticイニシャライザ後、読み取り専用にするので、ConcurrentHashMap を使用しません。 */ 112 private static final Map<String,String> MUST_PROPARTY ; // [プロパティ]必須チェック用 Map 113 /** staticイニシャライザ後、読み取り専用にするので、ConcurrentHashMap を使用しません。 */ 114 private static final Map<String,String> USABLE_PROPARTY ; // [プロパティ]整合性チェック Map 115 116 static { 117 MUST_PROPARTY = new LinkedHashMap<>(); 118 119 USABLE_PROPARTY = new LinkedHashMap<>(); 120 USABLE_PROPARTY.put( "dbid", "Process_DBParam の -configFile で指定する DBConfig.xml ファイルで規定" ); 121 USABLE_PROPARTY.put( "table", "INSERT する場合のテーブルID SQL文を指定する場合は不要。" ); 122 USABLE_PROPARTY.put( "sql", "更新SQL文(sql or sqlFile 必須)" + 123 CR + "例: \"UPDATE GE41 " + 124 CR + "SET NAME_JA = [NAME_JA],LABEL_NAME = [LABEL_NAME] " + 125 CR + "WHERE SYSTEM_ID = [SYSTEM_ID] AND CLM = [CLM]\"" ); 126 USABLE_PROPARTY.put( "sqlFile", "登録SQLファイル(sql or sqlFile 必須)例: update.sql" ); 127 USABLE_PROPARTY.put( "sql_", "SQL文中の{@XXXX}文字列を指定の固定値で置き換えます。" + 128 CR + "WHERE SYSTEM_ID='{@SYSTEM_ID}' ⇒ WHERE SYSTEM_ID='GE'" ); 129 USABLE_PROPARTY.put( "const_", "LineModel のキー(const_ に続く文字列)の値に、固定値を" + 130 CR + "設定します。キーが異なれば、複数のカラム名を指定できます。" + 131 CR + "例: -sql_SYSTEM_ID=GE" ); 132 // 4.0.0.0 (2007/09/21) 属性を追加 133 USABLE_PROPARTY.put( "omitClms", "-table 属性でINSERT文を自動作成する場合、取り除くカラム名を" + 134 CR + "CSV形式で複数指定できます。" + 135 CR + "例: -omitClms=UNIQ,FGJ,DYSET" ); 136 USABLE_PROPARTY.put( "initSql" , "開始時に一度だけ実行されるSQL文を指定します。" ); // 5.7.2.2 (2014/01/24) 追加 137 USABLE_PROPARTY.put( "initSqlFile", "開始時に一度だけ実行されるSQLファイルを指定します。" ); // 5.7.2.2 (2014/01/24) 追加 138 USABLE_PROPARTY.put( "endSql" , "終了時に一度だけ実行されるSQL文を指定します。" ); // 5.7.2.2 (2014/01/24) 追加 139 USABLE_PROPARTY.put( "endSqlFile" , "終了時に一度だけ実行されるSQLファイルを指定します。" ); // 5.7.2.2 (2014/01/24) 追加 140 USABLE_PROPARTY.put( "commitCnt", "指定数毎にコミットを発行します。" + 141 CR + "0 の場合は、終了までコミットしません(初期値:0)" ); 142 USABLE_PROPARTY.put( "display", "結果を標準出力に表示する(true)かしない(false)か" + 143 CR + "(初期値:false:表示しない)" ); 144 USABLE_PROPARTY.put( "debug", "デバッグ情報を標準出力に表示する(true)かしない(false)か" + 145 CR + "(初期値:false:表示しない)" ); // 5.7.3.0 (2014/02/07) デバッグ情報 146 } 147 148 /** 149 * デフォルトコンストラクター。 150 * このクラスは、動的作成されます。デフォルトコンストラクターで、 151 * super クラスに対して、必要な初期化を行っておきます。 152 * 153 */ 154 public Process_DBWriter() { 155 super( "org.opengion.fukurou.process.Process_DBWriter",MUST_PROPARTY,USABLE_PROPARTY ); 156 } 157 158 /** 159 * プロセスの初期化を行います。初めに一度だけ、呼び出されます。 160 * 初期処理(ファイルオープン、DBオープン等)に使用します。 161 * 162 * @og.rev 4.0.0.0 (2007/09/21) omitClms 属性を追加 163 * @og.rev 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応) 164 * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData を ConnectionFactory経由で取得。(PostgreSQL対応) 165 * @og.rev 5.7.2.2 (2014/01/24) initSql,initSqlFile,endSql,endSqlFile 追加 166 * 167 * @param paramProcess データベースの接続先情報などを持っているオブジェクト 168 */ 169 public void init( final ParamProcess paramProcess ) { 170 final Argument arg = getArgument(); 171 172 table = arg.getProparty("table"); 173 sql = arg.getFileProparty("sql","sqlFile",false); 174 endSql = arg.getFileProparty("endSql","endSqlFile",false); // 5.7.2.2 (2014/01/24) 追加 175 commitCnt = arg.getProparty("commitCnt",commitCnt); 176 display = arg.getProparty("display",display); 177 debug = arg.getProparty("debug",debug); // 5.7.3.0 (2014/02/07) デバッグ情報 178 179 dbid = arg.getProparty("dbid"); 180 connection = paramProcess.getConnection( dbid ); 181 // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応) 182 useParamMetaData = ConnectionFactory.useParameterMetaData( dbid ); // 5.3.8.0 (2011/08/01) 183 184 // 取り除くカラム名リストを配列に変換します。 185 final String tempClms = arg.getProparty("omitClms",null); 186 if( tempClms != null ) { 187 omitClms = StringUtil.csv2Array( tempClms ); 188 } 189 190 if( sql == null && table == null ) { 191 final String errMsg = "sql を指定しない場合は、table を必ず指定してください。"; 192 throw new OgRuntimeException( errMsg ); 193 } 194 195 // 3.8.0.1 (2005/06/17) {@DATE.XXXX} 変換処理の追加 196 // {@DATE.YMDH} などの文字列を、yyyyMMddHHmmss 型の日付に置き換えます。 197 // SQL文の {@XXXX} 文字列の固定値への置き換え 198 final HybsEntry[] entry =arg.getEntrys(SQL_KEY); // 配列 199 final SystemParameter sysParam = new SystemParameter( sql ); 200 sql = sysParam.replace( entry ); 201 202 // 5.7.2.2 (2014/01/24) initSql,endSql にも{@XXXX} 文字列の置き換えを行います。 203 String initSql = arg.getFileProparty("initSql","initSqlFile",false); // 5.7.2.2 (2014/01/24) 追加 204 if( initSql != null ) { 205 final SystemParameter sysParam2 = new SystemParameter( initSql ); 206 initSql = sysParam2.replace( entry ); 207 execSql( initSql ); 208 } 209 if( endSql != null ) { 210 final SystemParameter sysParam3 = new SystemParameter( endSql ); 211 endSql = sysParam3.replace( entry ); 212 } 213 214 final HybsEntry[] cnstKey = arg.getEntrys( CNST_KEY ); // 配列 215 final int csize = cnstKey.length; 216 cnstClm = new String[csize]; 217 constVal = new String[csize]; 218 for( int i=0; i<csize; i++ ) { 219 cnstClm[i] = cnstKey[i].getKey(); 220 constVal[i] = cnstKey[i].getValue(); 221 } 222 } 223 224 /** 225 * プロセスの終了を行います。最後に一度だけ、呼び出されます。 226 * 終了処理(ファイルクローズ、DBクローズ等)に使用します。 227 * 228 * @og.rev 4.0.0.0 (2007/11/27) commit,rollback,remove 処理を追加 229 * @og.rev 5.1.1.0 (2009/11/11) pMeta のクリア 230 * @og.rev 5.7.2.2 (2014/01/24) endSql 処理の追加 231 * 232 * @param isOK トータルで、OKだったかどうか[true:成功/false:失敗] 233 */ 234 public void end( final boolean isOK ) { 235 final boolean flag = Closer.stmtClose( pstmt ); 236 pstmt = null; 237 pMeta = null; // 5.1.1.0 (2009/11/11) 238 239 // 5.7.2.2 (2014/01/24) endSql の実行 240 Throwable th2 = null; 241 if( isOK && endSql != null ) { 242 try { execSql( endSql ); } catch( final Throwable th) { th2 = th ; } 243 } 244 245 // 5.7.2.2 (2014/01/24) すべて異常がない場合のみ、処理する様に変更。 246 if( isOK && flag && th2 == null ) { 247 Closer.commit( connection ); 248 } 249 else { 250 Closer.rollback( connection ); 251 } 252 ConnectionFactory.remove( connection,dbid ); 253 254 if( !flag ) { 255 final String errMsg = "ステートメントをクローズ出来ません。"; 256 throw new OgRuntimeException( errMsg ); 257 } 258 259 // 5.7.2.2 (2014/01/24) endSql の実行失敗時の処理 260 if( th2 != null ) { 261 final String errMsg = "endSql の実行に失敗しました。sql=[" + endSql + "]" + CR 262 + th2.getMessage() + CR ; 263 throw new OgRuntimeException( errMsg,th2 ); 264 } 265 } 266 267 /** 268 * 引数の LineModel を処理するメソッドです。 269 * 変換処理後の LineModel を返します。 270 * 後続処理を行わない場合(データのフィルタリングを行う場合)は、 271 * null データを返します。つまり、null データは、後続処理を行わない 272 * フラグの代わりにも使用しています。 273 * なお、変換処理後の LineModel と、オリジナルの LineModel が、 274 * 同一か、コピー(クローン)かは、各処理メソッド内で決めています。 275 * ドキュメントに明記されていない場合は、副作用が問題になる場合は、 276 * 各処理ごとに自分でコピー(クローン)して下さい。 277 * 278 * @og.rev 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応) 279 * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData setNull 対応(PostgreSQL対応) 280 * @og.rev 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 281 * 282 * @param data オリジナルのLineModel 283 * 284 * @return 処理変換後のLineModel 285 */ 286 public LineModel action( final LineModel data ) { 287 count++ ; 288 try { 289 if( firstRow ) { 290 pstmt = makePrepareStatement( table,data ); 291 // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応) 292 if( useParamMetaData ) { 293 pMeta = pstmt.getParameterMetaData(); 294 } 295 296 final int size = cnstClm.length; 297 cnstClmNos = new int[size]; 298 for( int i=0; i<size; i++ ) { 299 cnstClmNos[i] = data.getColumnNo( cnstClm[i] ); 300 } 301 302 firstRow = false; 303 if( display ) { println( data.nameLine() ); } // 5.7.3.0 (2014/02/07) デバッグ情報 304 } 305 306 // 固定値置き換え処理 307 for( int j=0; j<cnstClmNos.length; j++ ) { 308 data.setValue( cnstClmNos[j],constVal[j] ); 309 } 310 311 // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す。(PostgreSQL対応) 312 if( useParamMetaData ) { 313 for( int i=0; i<clmNos.length; i++ ) { 314 final int type = pMeta.getParameterType( i+1 ); 315 // 5.3.8.0 (2011/08/01) setNull 対応 316 final Object val = data.getValue(clmNos[i]); 317 if( val == null || ( val instanceof String && ((String)val).isEmpty() ) ) { 318 pstmt.setNull( i+1, type ); 319 } 320 else { 321 pstmt.setObject( i+1, val, type ); 322 } 323 } 324 } 325 else { 326 for( int i=0; i<clmNos.length; i++ ) { 327 pstmt.setObject( i+1,data.getValue(clmNos[i]) ); 328 } 329 } 330 331 pstmt.execute(); 332 if( commitCnt > 0 && ( count%commitCnt == 0 ) ) { 333 Closer.commit( connection ); 334 } 335 } 336 catch( final SQLException ex) { 337 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 338 final String errMsg = "SQL を実行できませんでした。" + CR 339 + "errMsg=[" + ex.getMessage() + "]" + CR 340 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 341 + "dbid=[" + dbid + "]" + CR 342 + "sql =[" + sql + "]" + CR 343 + "data=[" + data.dataLine() + "]" + CR ; 344 throw new OgRuntimeException( errMsg,ex ); 345 } 346 if( display ) { println( data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更 347 return data; 348 } 349 350 /** 351 * 内部で使用する PreparedStatement を作成します。 352 * 引数指定の SQL または、LineModel から作成した SQL より構築します。 353 * 354 * @og.rev 4.0.0.0 (2007/09/21) omitClms 属性を追加 355 * @og.rev 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 356 * @og.rev 6.2.3.0 (2015/05/01) CSV形式の作成を、String#join( CharSequence , CharSequence... )を使用。 357 * @og.rev 6.4.3.4 (2016/03/11) Formatterに新しいコンストラクターを追加する。 358 * 359 * @param table 処理対象のテーブルID 360 * @param data 処理対象のLineModel 361 * 362 * @return PreparedStatementオブジェクト 363 */ 364 private PreparedStatement makePrepareStatement( final String table,final LineModel data ) { 365 if( sql == null ) { 366 String[] names = data.getNames(); 367 368 // カラムを取り除く場合 369 if( omitClms != null ) { 370 final Set<String> set = new HashSet<>(); 371 for( int i=0; i<names.length; i++ ) { 372 set.add( names[i] ); 373 } 374 for( int i=0; i<omitClms.length; i++ ) { 375 set.remove( omitClms[i] ); 376 } 377 names = set.toArray( new String[set.size()] ); 378 } 379 final int size = names.length; 380 381 // 6.2.3.0 (2015/05/01) CSV形式の作成を、String#join( CharSequence , CharSequence... )を使用。 382 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ) 383 .append( "INSERT INTO " ).append( table ).append( " (" ) 384 .append( String.join( "," , names ) ) // 6.2.3.0 (2015/05/01) 385 .append( " ) VALUES ( ?" ); 386 for( int i=1; i<size; i++ ) { 387 buf.append( ",?" ); 388 } 389 buf.append( " )" ); 390 sql = buf.toString(); 391 392 // カラム番号を設定します。 393 clmNos = new int[size]; 394 for( int i=0; i<size; i++ ) { 395 clmNos[i] = data.getColumnNo( names[i] ); // 4.0.0.0 (2007/09/21) 396 } 397 } 398 else { 399 final Formatter format = new Formatter( data,sql ); // 6.4.3.4 (2016/03/11) 400 sql = format.getQueryFormatString(); 401 clmNos = format.getClmNos(); 402 } 403 404 final PreparedStatement ps ; 405 try { 406 ps = connection.prepareStatement( sql ); 407 } 408 catch( final SQLException ex) { 409 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 410 final String errMsg = "PreparedStatement を取得できませんでした。" + CR 411 + "errMsg=[" + ex.getMessage() + "]" + CR 412 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 413 + "dbid =[" + dbid + "]" + CR 414 + "sql =[" + sql + "]" + CR 415 + "table=[" + table + "]" + CR 416 + "data =[" + data.dataLine() + "]" + CR ; 417 throw new OgRuntimeException( errMsg,ex ); 418 } 419 420 return ps; 421 } 422 423 /** 424 * SQL処理を実行します。 425 * 主に、initSql,endSqlの実行用です。 426 * ここでは、エラーが発生しても、connection は閉じません。 427 * 最終的に、endメソッドで処理されるためです。 428 * 429 * @og.rev 5.7.2.2 (2014/01/24) 新規追加 430 * @og.rev 6.4.2.1 (2016/02/05) try-with-resources 文で記述。 431 * 432 * @param sql 実行するSQL文 433 */ 434 private void execSql( final String sql ) { 435 // 6.4.2.1 (2016/02/05) try-with-resources 文 436 try( final Statement stmt = connection.createStatement() ) { 437 stmt.execute( sql ); 438 } 439 catch( final SQLException ex) { // catch は、close() されてから呼ばれます。 440 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します。 441 final String errMsg = "SQL を実行できませんでした。" + CR 442 + "errMsg=[" + ex.getMessage() + "]" + CR 443 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 444 + "dbid=[" + dbid + "]" + CR 445 + "sql =[" + sql + "]" + CR ; 446 throw new OgRuntimeException( errMsg,ex ); 447 } 448 } 449 450 /** 451 * プロセスの処理結果のレポート表現を返します。 452 * 処理プログラム名、入力件数、出力件数などの情報です。 453 * この文字列をそのまま、標準出力に出すことで、結果レポートと出来るような 454 * 形式で出してください。 455 * 456 * @return 処理結果のレポート 457 */ 458 public String report() { 459 final String report = "[" + getClass().getName() + "]" + CR 460 + TAB + "DBID : " + dbid + CR 461 + TAB + "Output Count : " + count ; 462 463 return report ; 464 } 465 466 /** 467 * このクラスの使用方法を返します。 468 * 469 * @return このクラスの使用方法 470 * @og.rtnNotNull 471 */ 472 public String usage() { 473 final StringBuilder buf = new StringBuilder( BUFFER_LARGE ) 474 .append( "Process_DBWriter は、上流から受け取ったデータをデータベースに書き込む" ).append( CR ) 475 .append( "CainProcess インターフェースの実装クラスです。" ).append( CR ) 476 .append( CR ) 477 .append( "上流(プロセスチェインのデータは上流から下流へと渡されます。)から" ).append( CR ) 478 .append( "受け取った LineModel を元に、データベースへの書き込みを行います。" ).append( CR ) 479 .append( CR ) 480 .append( "データベース接続先等は、ParamProcess のサブクラス(Process_DBParam)に" ).append( CR ) 481 .append( "設定された接続(Connection)を使用します。" ).append( CR ) 482 .append( CR ) 483 .append( "引数文字列中に空白を含む場合は、ダブルコーテーション(\"\") で括って下さい。" ).append( CR ) 484 .append( "引数文字列の 『=』の前後には、空白は挟めません。必ず、-key=value の様に" ).append( CR ) 485 .append( "繋げてください。" ).append( CR ) 486 .append( CR ) 487 .append( "SQL文には、{@DATE.YMDH}等のシステム変数が使用できます。" ).append( CR ) 488 .append( CR ).append( CR ) 489 .append( getArgument().usage() ).append( CR ); 490 491 return buf.toString(); 492 } 493 494 /** 495 * このクラスは、main メソッドから実行できません。 496 * 497 * @param args コマンド引数配列 498 */ 499 public static void main( final String[] args ) { 500 LogWriter.log( new Process_DBWriter().usage() ); 501 } 502}