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 * @og.rev 5.6.9.4 (2013/10/31) エラーメ?ージに?行前の??も?力します? 087 * 088 * @param rowNo 選択された行番号配?(登録する対象? 089 * @param table DBTableModelオブジェク?登録する?ータ) 090 */ 091 @Override 092 public void execute( final int[] rowNo, final DBTableModel table ) { 093 PreparedStatement pstmt = null ; 094 // ParameterMetaData pMeta = null ; // 5.5.5.4 (2012/08/18) useParamMetaData 処?、ループ?外に出す?( 095 096 int row = 0; // エラー時に表示するエラー行番号 097 try { 098 int executeCount = 0; // 処?数 099 Formatter form = new Formatter( table ); 100 form.setFormat( getStatement() ); 101 int[] clmNos = form.getClmNos(); // 引数の個数??配?。カラ?号を保? 102 String query = form.getQueryFormatString(); 103 int cnt = clmNos.length; // 引数の個数(カラ??個数ではありません? 104 105 // 5.5.5.4 (2012/08/18) Timestamp オブジェクトを登録できるようにする? 106 boolean useTimeStamp = false; 107 boolean[] isTime = new boolean[cnt]; 108 for( int j=0; j<cnt; j++ ) { 109 // 5.5.8.5 (2012/11/27) TIMESTAMP型でも??きるようにします? 110 // isTime[j] = "DATE".equalsIgnoreCase( table.getDBColumn( clmNos[j] ).getClassName() ); 111 String clsName = table.getDBColumn( clmNos[j] ).getClassName(); 112 isTime[j] = "DATE".equalsIgnoreCase( clsName ) || "TIMESTAMP".equalsIgnoreCase( clsName ); 113 if( !useTimeStamp && isTime[j] ) { useTimeStamp = true; } // isTime[j] == true 時に、??実行される? 114 } 115 116 Connection conn = getConnection(); 117 pstmt = conn.prepareStatement( query ); 118 pstmt.setQueryTimeout( DB_MAX_QUERY_TIMEOUT ); 119 // ((oracle.jdbc.OraclePreparedStatement)pstmt).setExecuteBatch(50); 120 // 4.0.0.0 (2007/09/25) isOracle から useParamMetaData に変更 121 // boolean useParamMetaData = ApplicationInfo.useParameterMetaData( conn ); 122 boolean useParamMetaData = useParameterMetaData(); // 5.3.8.0 (2011/08/01) 123 124 // 5.5.5.4 (2012/08/18) 以下?useParamMetaData、useTimeStamp??常の?種類を、行?ループ?外に出す? 125 // 5.5.5.4 (2012/08/18) useParamMetaData 処?、ループ?外に出す?(PostgreSQL対? 126 if( useParamMetaData ) { 127 int[] types = new int[cnt]; 128 ParameterMetaData pMeta = pstmt.getParameterMetaData(); 129 for( int j=0; j<cnt; j++ ) { 130 types[j] = pMeta.getParameterType( j+1 ); // ?こし?配?の個数と添え字?関係から?j と j+1 での処?なる? 131 } 132 133 for( int i=0; i<rowNo.length; i++ ) { 134 row = rowNo[i]; 135 for( int j=0; j<cnt; j++ ) { 136 String val = StringUtil.rTrim( table.getValue( row,clmNos[j] ) ); 137 if( val == null || val.isEmpty() ) { 138 pstmt.setNull( j+1, types[j] ); 139 } 140 else { 141 pstmt.setObject( j+1, val, types[j] ); 142 } 143 } 144 executeCount += pstmt.executeUpdate(); 145 } 146 } 147 // 5.5.5.4 (2012/08/18) PostgreSQL対?以外?DBの場? 148 else { 149 // 5.5.5.4 (2012/08/18) Timestamp オブジェクトを登録する場? 150 if( useTimeStamp ) { 151 for( int i=0; i<rowNo.length; i++ ) { 152 row = rowNo[i]; 153 for( int j=0; j<cnt; j++ ) { 154 String val = StringUtil.rTrim( table.getValue( row,clmNos[j] ) ); 155 if( isTime[j] && val != null && !val.isEmpty() ) { 156 // 5.5.8.5 (2012/11/27) val は、yyyy-mm-dd hh:mm:ss[.f...] 形式でなければならな?? 157 // java.sql.Timestamp time = java.sql.Timestamp.valueOf( val ); 158 java.sql.Timestamp time = java.sql.Timestamp.valueOf( HybsDateUtil.parseTimestamp( val ) ); 159 pstmt.setObject( j+1,time ); 160 } 161 else { 162 pstmt.setObject( j+1,val ); 163 } 164 } 165 executeCount += pstmt.executeUpdate(); 166 } 167 } 168 // 5.5.5.4 (2012/08/18) そ?他:つまり?これが?常の処? 169 else { 170 for( int i=0; i<rowNo.length; i++ ) { 171 row = rowNo[i]; 172 for( int j=0; j<cnt; j++ ) { 173 String val = StringUtil.rTrim( table.getValue( row,clmNos[j] ) ); 174 pstmt.setObject( j+1,val ); 175 } 176 executeCount += pstmt.executeUpdate(); 177 } 178 } 179 } 180 // if( useParamMetaData ) { pMeta = pstmt.getParameterMetaData(); } 181 // for( int i=0; i<rowNo.length; i++ ) { 182 // row = rowNo[i]; 183 // for( int j=0; j<cnt; j++ ) { 184 //// String val = table.getValue( row,clmNos[j] ) ; // 5.3.8.0 (2011/08/01) 簡? 185 // String val = StringUtil.rTrim( table.getValue( row,clmNos[j] ) ); 186 // // 4.0.0.0 (2007/09/25) ParameterMetaData を使用したパラメータ設定追? 187 // if( useParamMetaData ) { 188 // int type = pMeta.getParameterType( j+1 ); 189 // // 5.3.8.0 (2011/08/01) setNull 対? 190 //// pstmt.setObject( j+1,StringUtil.rTrim( val ),type ); 191 // if( val == null || val.isEmpty() ) { 192 // pstmt.setNull( j+1, type ); 193 // } 194 // else { 195 // pstmt.setObject( j+1, val, type ); 196 // } 197 // } 198 // else { 199 //// pstmt.setObject( j+1,StringUtil.rTrim( val ) ); 200 // pstmt.setObject( j+1,val ); 201 // } 202 // } 203 // executeCount += pstmt.executeUpdate(); 204 // } 205 setExecuteCount( executeCount ); 206 setErrorCode( ErrorMessage.OK ); 207 } 208 catch (SQLException ex) { 209 setErrorCode( ErrorMessage.EXCEPTION ); 210 String errMsg = ex.getMessage() + ":" + ex.getSQLState() + HybsSystem.CR 211 + " QUERY=" + getStatement() + HybsSystem.CR 212 + " ROW =[" + (row+1) + "]" + HybsSystem.CR 213 + " VALS=[" + StringUtil.array2csv( table.getValues(row) )+ "]" + HybsSystem.CR ; 214 // 5.6.9.4 (2013/10/31) 215 if( row > 0 ) { 216 errMsg = errMsg 217 + " ROW(-1) =[" + (row) + "]" + HybsSystem.CR 218 + " VALS(-1)=[" + StringUtil.array2csv( table.getValues(row-1) )+ "]" + HybsSystem.CR ; 219 } 220 rollback(); 221 realClose(); 222 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び?更 223 } 224 finally { 225 Closer.stmtClose( pstmt ); 226 } 227 } 228 }