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 = "5.6.9.4 (2013/10/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 }