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 }