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