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.plugin.query; 017 018import org.opengion.hayabusa.db.AbstractQuery; 019import org.opengion.hayabusa.db.DBErrMsg; 020import org.opengion.hayabusa.common.HybsSystemException; 021import org.opengion.fukurou.util.ErrorMessage; 022import org.opengion.fukurou.util.StringUtil; 023 024import java.sql.Connection; 025import java.sql.CallableStatement; 026import java.sql.ResultSet; 027import java.sql.SQLException; 028import java.sql.Types; 029import java.sql.Array; // 6.0.0.0 (2014/04/11) Oracle11g(11.2.0.3のドライバ) 対応。oracle.sql.ARRAY の置き換え 030import oracle.jdbc.OracleConnection; // 6.0.0.0 (2014/04/11) Oracle11g(11.2.0.3のドライバ) 対応 031 032import oracle.jdbc.OracleTypes; // CURSOR が残る 033import oracle.jdbc.OracleCallableStatement; // CURSOR が残る 034 035import java.util.Map; 036 037/** 038 * エントリ系 PL/SQL をコールして、結果カーソルから、DBTableModel を作成します。 039 * 040 * java.sql.CallableStatement を用いて、データベース検索処理を行います。 041 * 引数を配列指定で渡すことが出来,エラー時には、DBErrMsg オブジェクトにエラー情報を 042 * 格納して返すことが可能です。 043 * 内部変数の受け渡しのデフォルト実装は、AbstractQuery クラスを継承している 044 * ため,ここでは、execute() メソッドを実装しています。 045 * このクラスでは、ステートメント文を execute() する事により,データベースを 046 * 検索した結果を DBTableModel に割り当てます。 047 * 048 * @og.formSample 049 * 例:jsp/TYPESB/result.jsp (検索系:カーソル返し) 050 * 例:jsp/TYPE3B/entry.jsp (エントリ系) 051 * names には、ARG_ARRAY 配列に順次セットされます。 052 * 使用する場合は、一旦わかり易い変数に受けて利用してください。 053 * 呼び出す PL/SQL では、検索系PL/SQL です。(下記の例は、エントリ系) 054 * 055 * <og:query 056 * command = "NEW" 057 * names = "SYSTEM_ID,LANG,CLM,NAME_JA,LABEL_NAME,KBSAKU,USER.ID" 058 * queryType = "JDBCErrMsg" 059 * displayMsg = "" > 060 * {call TYPE3B01.TYPE3B01(?,?,?,?)} 061 * </og:query> 062 * 063 * CREATE OR REPLACE PACKAGE TYPE3B01 AS 064 * TYPE CUST_CURSOR IS REF CURSOR; 065 * PROCEDURE TYPE3B01( 066 * P_KEKKA OUT NUMBER, 067 * P_ERRMSGS OUT ERR_MSG_ARRAY, 068 * P_RC1 OUT CUST_CURSOR, 069 * P_ARGS IN ARG_ARRAY ); 070 * END; 071 * 072 * P_SYSTEM_ID GEA08.SYSTEM_ID%TYPE := P_ARGS(1); --システムID 073 * P_LANG GEA08.LANG%TYPE := P_ARGS(2); --言語 074 * P_CLM GEA08.CLM%TYPE := P_ARGS(3); --項目 075 * P_NAME_JA GEA08.NAME_JA%TYPE := P_ARGS(4); --名称(漢字) 076 * P_LABEL_NAME GEA08.LABEL_NAME%TYPE := P_ARGS(5); --表示名称 077 * P_KBSAKU GEA08.KBSAKU%TYPE := P_ARGS(6); --作成区分 078 * P_USRSET GEA08.USRSET%TYPE := P_ARGS(7); --登録者 079 * 080 * @og.group データ表示 081 * @og.group データ編集 082 * 083 * @version 4.0 084 * @author Kazuhiko Hasegawa 085 * @since JDK5.0, 086 */ 087public class Query_JDBCErrMsg extends AbstractQuery { 088 /** このプログラムのVERSION文字列を設定します。 {@value} */ 089 private static final String VERSION = "6.4.2.1 (2016/02/05)" ; 090 091 /** 092 * デフォルトコンストラクター 093 * 094 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 095 */ 096 public Query_JDBCErrMsg() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 097 098 /** 099 * 引数配列付のクエリーを実行します。 100 * 処理自体は, #execute() と同様に、各サブクラスの実装に依存します。 101 * これは、CallableStatement を用いて、データベース検索処理を行います。 102 * {call TYPE3B01.TYPE3B01(?,?,?,?)} で、4番目の引数には、 103 * names で指定したリクエスト情報が、ARG_ARRAY 配列に順次セットされます。 104 * 使用する場合は、一旦わかり易い変数に受けて利用してください。 105 * 呼び出す PL/SQL では、検索系PL/SQL です。 106 * 107 * @og.rev 2.3.1.3 (2003/01/28) Open Cursor が、大量に残る件の対応。ResultSet を close() 108 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 109 * @og.rev 3.3.3.1 (2003/07/18) DB登録時の後ろスペースを削除する。 110 * @og.rev 3.5.2.0 (2003/10/20) 内部オブジェクトタイプ名を システムパラメータ で定義します。 111 * @og.rev 3.5.6.0 (2004/06/18) nullに対する無駄な比較を削除します。 112 * @og.rev 3.8.0.8 (2005/10/03) エラーメッセージの出力順をメッセージ+Queryに変更します。 113 * @og.rev 6.0.0.0 (2014/04/11) Oracle11g(11.2.0.3のドライバ)対応 114 * @og.rev 6.3.6.1 (2015/08/28) close(),realClose() 廃止。Queryはキャッシュしません。 115 * @og.rev 6.4.2.1 (2016/02/05) try-with-resources 文で記述。 116 * @og.rev 6.9.3.0 (2018/03/26) DB_FETCH_SIZE追加。 117 * 118 * @param args オブジェクトの引数配列(可変長引数) 119 */ 120 @Override 121 public void execute( final String... args ) { // 6.1.1.0 (2015/01/17) refactoring 122 try { 123 final Connection conn = getConnection(); 124 // 6.4.2.1 (2016/02/05) try-with-resources 文 125 try( CallableStatement callStmt = conn.prepareCall( getStatement() ) ) { 126 callStmt.setQueryTimeout( DB_MAX_QUERY_TIMEOUT ); 127 callStmt.setFetchSize( DB_FETCH_SIZE ); // 6.9.3.0 (2018/03/26) 128 129 final Map<String,Class<?>> map = conn.getTypeMap(); 130 map.put( ERR_MSG,DBErrMsg.class ); // 4.0.0 (2005/01/31) 131 132 // 6.0.0.0 (2014/04/11) Oracle11g(11.2.0.3のドライバ)対応 http://docs.oracle.com/cd/E28389_01/web.1111/b60995/thirdparty.htm 133 final Array newArray = ((OracleConnection)conn).createOracleArray( ARG_ARRAY, StringUtil.rTrims( args )); // 6.0.0.0 (2014/04/11) Oracle11g(11.2.0.3のドライバ)対応 134 135 callStmt.registerOutParameter(1, Types.INTEGER); 136 callStmt.registerOutParameter(2, Types.ARRAY,ERR_MSG_ARRAY); // 6.0.0.0 (2014/04/11) Oracle11g(11.2.0.3のドライバ)対応 137 callStmt.registerOutParameter(3, OracleTypes.CURSOR); 138 callStmt.setArray( 4,newArray ); // 6.0.0.0 (2014/04/11) Oracle11g(11.2.0.3のドライバ)対応 139 140 callStmt.execute(); 141 142 final int rtnCode = callStmt.getInt(1); 143 setErrorCode( rtnCode ); 144 if( rtnCode < ErrorMessage.NG ) { // 異常以外の場合 145 try( final ResultSet resultSet = ((OracleCallableStatement)callStmt).getCursor(3) ) { 146 createTableModel( resultSet ); 147 } 148 } 149 if( rtnCode > ErrorMessage.OK ) { // 正常以外の場合 150 final Array rtn3 = callStmt.getArray(2); // 6.0.0.0 (2014/04/11) Oracle11g(11.2.0.3のドライバ)対応 151 final Object[] rtnval3 = (Object[])rtn3.getArray(); 152 final ErrorMessage errMessage = new ErrorMessage( "Query_JDBCErrMsg Error!!" ); 153 for( int i=0; i<rtnval3.length; i++ ) { 154 final DBErrMsg er = (DBErrMsg)rtnval3[i]; 155 if( er == null ) { break; } 156 errMessage.addMessage( er.getErrMsg() ); 157 } 158 setErrorMessage( errMessage ); 159 } 160 } 161 } 162 catch( final SQLException ex) { 163 setErrorCode( ErrorMessage.EXCEPTION ); 164 final String errMsg = ex.getMessage() + ":" + ex.getSQLState() + CR 165 + getStatement() + CR; 166 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び順変更 167 } 168 } 169}