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 */ 016 package org.opengion.plugin.query; 017 018 import org.opengion.hayabusa.db.AbstractQuery; 019 import org.opengion.hayabusa.db.DBTableModel; 020 import org.opengion.hayabusa.common.HybsSystem; 021 import org.opengion.hayabusa.common.HybsSystemException; 022 import org.opengion.fukurou.util.ErrorMessage; 023 import org.opengion.fukurou.util.StringUtil; 024 import org.opengion.fukurou.util.Closer; 025 import org.opengion.fukurou.util.HybsDateUtil; // 5.5.8.5 (2012/11/27) 026 import org.opengion.fukurou.model.Formatter; 027 028 import java.sql.Connection; 029 import java.sql.PreparedStatement; 030 import java.sql.ParameterMetaData; 031 import java.sql.SQLException; 032 033 /** 034 * 引数引き当て(PreparedStatement) を利用した登録系Queryです? 035 * 036 * java.sql.PreparedStatement を用?、データベ?ス検索処?行います? 037 * 引数の?方法?、DBTableModele のカラ?に対応する名称を?SQL??[カラ?]形式で 038 * 記述します?これを解析して、実際に実行す?PreparedStatement に対応する文字?? 039 * 作?します? 040 * たとえ?、INSERT INTO GEXX (CLM,NAME_JA,LABEL_NAME) VALUES ([CLM],[NAME_JA],[LABEL_NAME] ) 041 * と記述すれば、?部で、DBTableModele のカラ?に対応する?を取り?し?SQL?して? 042 * INSERT INTO GEXX (CLM,NAME_JA,LABEL_NAME) VALUES (?,?,? ) を実行します? 043 * 044 * @og.formSample 045 * ●使用? 046 * 047 * ・QUERYを直接書く?? 048 * 【entry.jsp? 049 * <og:tableUpdate 050 * command = "{@command}" 051 * queryType = "JDBCTableUpdate" 052 * > 053 * INSERT INTO GE41 054 * (CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG, 055 * FGJ,DYSET,DYUPD,USRSET,USRUPD,PGUPD) 056 * VALUES 057 * ([CLM],[NAME_JA],[LABEL_NAME],[KBSAKU],[SYSTEM_ID],[LANG], 058 * '1','{@USER.YMDH}','{@USER.YMDH}','{@USER.ID}','{@USER.ID}','{@GUI.KEY}') 059 * </og:tableUpdate> 060 * 061 * @og.rev 4.0.0.0 (2005/01/31) 新規作? 062 * @og.group ??タ編? 063 * 064 * @version 4.0 065 * @author Kazuhiko Hasegawa 066 * @since JDK5.0, 067 */ 068 public class Query_JDBCTableUpdate extends AbstractQuery { 069 //* こ?プログラ??VERSION??を設定します? {@value} */ 070 private static final String VERSION = "4.0.0.0 (2005/08/31)" ; 071 072 /** 073 * 引数配?付?クエリーを実行します? 074 * 処??体?, #execute() と同様に、各サブクラスの実?依存します? 075 * これは、PreparedQuery で使用する引数を?列でセ?するも?です? 076 * select * from emp where deptno = ? and job = ? などの PreparedQuery の 077 * [カラ?] 部??引数を?DBTableModelから?にセ?して?ます? 078 * 079 * @og.rev 3.8.0.8 (2005/10/03) エラーメ?ージの出力?をメ?ージ?Queryに変更します? 080 * @og.rev 4.0.0.0 (2007/05/09) ParameterMetaData を使用したパラメータ設定追?? 081 * @og.rev 4.0.0.0 (2007/09/25) isOracle から useParamMetaData に変更 082 * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData ?ConnectionFactory経由で取得?(PostgreSQL対?、setNull 対? 083 * @og.rev 5.5.5.4 (2012/08/18) useParamMetaData 処?、ループ?外に出す?(PostgreSQL対? 084 * @og.rev 5.5.5.4 (2012/08/18) DATE オブジェクトを登録できるようにする? 085 * @og.rev 5.5.8.5 (2012/11/27) TIMESTAMP型でも??きるようにします? 086 * 087 * @param rowNo 選択された行番号配?(登録する対象? 088 * @param table DBTableModelオブジェク?登録する?ータ) 089 */ 090 @Override 091 public void execute( final int[] rowNo, final DBTableModel table ) { 092 PreparedStatement pstmt = null ; 093 // ParameterMetaData pMeta = null ; // 5.5.5.4 (2012/08/18) useParamMetaData 処?、ループ?外に出す?( 094 095 int row = 0; // エラー時に表示するエラー行番号 096 try { 097 int executeCount = 0; // 処?数 098 Formatter form = new Formatter( table ); 099 form.setFormat( getStatement() ); 100 int[] clmNos = form.getClmNos(); // 引数の個数??配?。カラ?号を保? 101 String query = form.getQueryFormatString(); 102 int cnt = clmNos.length; // 引数の個数(カラ??個数ではありません? 103 104 // 5.5.5.4 (2012/08/18) Timestamp オブジェクトを登録できるようにする? 105 boolean useTimeStamp = false; 106 boolean[] isTime = new boolean[cnt]; 107 for( int j=0; j<cnt; j++ ) { 108 // 5.5.8.5 (2012/11/27) TIMESTAMP型でも??きるようにします? 109 // isTime[j] = "DATE".equalsIgnoreCase( table.getDBColumn( clmNos[j] ).getClassName() ); 110 String clsName = table.getDBColumn( clmNos[j] ).getClassName(); 111 isTime[j] = "DATE".equalsIgnoreCase( clsName ) || "TIMESTAMP".equalsIgnoreCase( clsName ); 112 if( !useTimeStamp && isTime[j] ) { useTimeStamp = true; } // isTime[j] == true 時に、??実行される? 113 } 114 115 Connection conn = getConnection(); 116 pstmt = conn.prepareStatement( query ); 117 pstmt.setQueryTimeout( DB_MAX_QUERY_TIMEOUT ); 118 // ((oracle.jdbc.OraclePreparedStatement)pstmt).setExecuteBatch(50); 119 // 4.0.0.0 (2007/09/25) isOracle から useParamMetaData に変更 120 // boolean useParamMetaData = ApplicationInfo.useParameterMetaData( conn ); 121 boolean useParamMetaData = useParameterMetaData(); // 5.3.8.0 (2011/08/01) 122 123 // 5.5.5.4 (2012/08/18) 以下?useParamMetaData、useTimeStamp??常の?種類を、行?ループ?外に出す? 124 // 5.5.5.4 (2012/08/18) useParamMetaData 処?、ループ?外に出す?(PostgreSQL対? 125 if( useParamMetaData ) { 126 int[] types = new int[cnt]; 127 ParameterMetaData pMeta = pstmt.getParameterMetaData(); 128 for( int j=0; j<cnt; j++ ) { 129 types[j] = pMeta.getParameterType( j+1 ); // ?こし?配?の個数と添え字?関係から?j と j+1 での処?なる? 130 } 131 132 for( int i=0; i<rowNo.length; i++ ) { 133 row = rowNo[i]; 134 for( int j=0; j<cnt; j++ ) { 135 String val = StringUtil.rTrim( table.getValue( row,clmNos[j] ) ); 136 if( val == null || val.isEmpty() ) { 137 pstmt.setNull( j+1, types[j] ); 138 } 139 else { 140 pstmt.setObject( j+1, val, types[j] ); 141 } 142 } 143 executeCount += pstmt.executeUpdate(); 144 } 145 } 146 // 5.5.5.4 (2012/08/18) PostgreSQL対?以外?DBの場? 147 else { 148 // 5.5.5.4 (2012/08/18) Timestamp オブジェクトを登録する場? 149 if( useTimeStamp ) { 150 for( int i=0; i<rowNo.length; i++ ) { 151 row = rowNo[i]; 152 for( int j=0; j<cnt; j++ ) { 153 String val = StringUtil.rTrim( table.getValue( row,clmNos[j] ) ); 154 if( isTime[j] && val != null && !val.isEmpty() ) { 155 // 5.5.8.5 (2012/11/27) val は、yyyy-mm-dd hh:mm:ss[.f...] 形式でなければならな?? 156 // java.sql.Timestamp time = java.sql.Timestamp.valueOf( val ); 157 java.sql.Timestamp time = java.sql.Timestamp.valueOf( HybsDateUtil.parseTimestamp( val ) ); 158 pstmt.setObject( j+1,time ); 159 } 160 else { 161 pstmt.setObject( j+1,val ); 162 } 163 } 164 executeCount += pstmt.executeUpdate(); 165 } 166 } 167 // 5.5.5.4 (2012/08/18) そ?他:つまり?これが?常の処? 168 else { 169 for( int i=0; i<rowNo.length; i++ ) { 170 row = rowNo[i]; 171 for( int j=0; j<cnt; j++ ) { 172 String val = StringUtil.rTrim( table.getValue( row,clmNos[j] ) ); 173 pstmt.setObject( j+1,val ); 174 } 175 executeCount += pstmt.executeUpdate(); 176 } 177 } 178 } 179 // if( useParamMetaData ) { pMeta = pstmt.getParameterMetaData(); } 180 // for( int i=0; i<rowNo.length; i++ ) { 181 // row = rowNo[i]; 182 // for( int j=0; j<cnt; j++ ) { 183 //// String val = table.getValue( row,clmNos[j] ) ; // 5.3.8.0 (2011/08/01) 簡? 184 // String val = StringUtil.rTrim( table.getValue( row,clmNos[j] ) ); 185 // // 4.0.0.0 (2007/09/25) ParameterMetaData を使用したパラメータ設定追? 186 // if( useParamMetaData ) { 187 // int type = pMeta.getParameterType( j+1 ); 188 // // 5.3.8.0 (2011/08/01) setNull 対? 189 //// pstmt.setObject( j+1,StringUtil.rTrim( val ),type ); 190 // if( val == null || val.isEmpty() ) { 191 // pstmt.setNull( j+1, type ); 192 // } 193 // else { 194 // pstmt.setObject( j+1, val, type ); 195 // } 196 // } 197 // else { 198 //// pstmt.setObject( j+1,StringUtil.rTrim( val ) ); 199 // pstmt.setObject( j+1,val ); 200 // } 201 // } 202 // executeCount += pstmt.executeUpdate(); 203 // } 204 setExecuteCount( executeCount ); 205 setErrorCode( ErrorMessage.OK ); 206 } 207 catch (SQLException ex) { 208 setErrorCode( ErrorMessage.EXCEPTION ); 209 String errMsg = ex.getMessage() + ":" + ex.getSQLState() + HybsSystem.CR 210 + "QUERY=" + getStatement() + HybsSystem.CR 211 + "ROW=[" + (row+1) + "]" 212 + " VALS=[" + StringUtil.array2csv( table.getValues(row) ) 213 + HybsSystem.CR ; 214 rollback(); 215 realClose(); 216 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び?更 217 } 218 finally { 219 Closer.stmtClose( pstmt ); 220 } 221 } 222 }