exec( ParamSet param_set ) { clearResults(); msg.LockConnection(); try { String schema = procInfo.getSchema(); bool needEOG = true; AdvanRSMD rsmd; msg.begin( MSG_QUERY ); msg.write( MSG_QRY_EXP ); if ( conn.msg_protocol_level >= MSG_PROTO_3 ) { msg.write( MSG_QP_FLAGS ); msg.write( (short)4 ); msg.write( MSG_QF_FETCH_FIRST | MSG_QF_AUTO_CLOSE ); needEOG = false; } if ( schema != null ) { msg.write( MSG_QP_SCHEMA_NAME ); msg.write( schema ); } msg.write( MSG_QP_PROC_NAME ); msg.write( procInfo.getName() ); if ( procInfo.getParamCount() < 1 ) msg.done( true ); else { msg.done( false ); param_set.sendDesc(false); param_set.sendData(true); } if ( (rsmd = readResults( timeout, needEOG )) == null ) { /* ** Procedure execute has completed and all results have ** been returned. Unlock the connection. */ if ( msg.moreMessages() ) readResults( timeout, true ); msg.UnlockConnection(); } else if ( hasByRefParam ) { /* ** BYREF parameters are treated as a result-set with ** exactly one row and processed as a tuple stream. ** The BYREF parameter result-set class loads the single ** row, shuts the statement and unlocks the connection. */ resultRow = new RsltByref( conn, this, rsmd, rslt_val_stmt, msg.moreMessages() ); /* ** Map output parameters to the output result-set. */ for( int i = 0, index = 0; i < opMap.Length; i++ ) if ( opMap[ i ] >= 0 ) opMap[ i ] = index++; } else { /* ** Procedure result rows are handled like select loop ** results and the connection will be unlocked when ** the end of the result set is reached. */ resultSet = new RsltSlct( conn, this, rsmd, rslt_val_stmt, getPreFetchSize(), msg.moreMessages() ); } } catch( SqlEx ex ) { if ( trace.enabled() ) trace.log( title + ".execute(): error executing procedure" ); if ( trace.enabled( 1 ) ) ex.trace( trace ); msg.UnlockConnection(); throw ex; } return; } // exec
addBatch() { if (trace.enabled()) trace.log(title + ".addBatch()"); checkParams( paramSet ); if ( batch == null ) newBatch(); lock( batch ) { if ( hasByRefParam ) { batch.Add( null ); paramSet.clear( false ); } else { batch.Add( paramSet ); paramSet = new ParamSet( conn ); } initParameters(); } return; } // addBatch
/* ** Name: exec ** ** Description: ** Execute a prepared statement. ** ** Input: ** param_set Parameters ** ** Output: ** None. ** ** Returns: ** void. ** ** History: ** 19-May-99 (gordy) ** Created. ** 8-Sep-99 (gordy) ** Synchronize on DbConn. ** 29-Sep-99 (gordy) ** Use DbConn lock()/unlock() methods for ** synchronization to support BLOB streams. ** 15-Nov-99 (gordy) ** Pass max row count and column length to result set. ** 16-Nov-99 (gordy) ** Added query timeouts. ** 13-Dec-99 (gordy) ** Added fetch limit. ** 19-Oct-00 (gordy) ** Re-prepare the statement if transaction state changed. ** 8-Jan-01 (gordy) ** Parameter set passed as parameter to support batch processing. ** 3-Mar-01 (gordy) ** Centralize call to clearResults in exec(). ** 16-Apr-01 (gordy) ** RSMD may change between prepare and execute (nasty!). We ** can't do anything about the application seeing the change, ** but we must use the execute RSMD to read the result-set. ** 10-May-01 (gordy) ** Only use execute RSMD if one actually arrives. ** 20-Jun-01 (gordy) ** Pass cursor name to result-set according to spec: ** NULL if READONLY and not provided by application. ** 20-Aug-01 (gordy) ** Send READONLY flag to server. Warn if cursor mode changed ** to READONLY. ** 31-Oct-02 (gordy) ** Adapted for generic GCF driver. ** 25-Feb-03 (gordy) ** Check that all contiguous parameters have been provided ** (we don't know actual dynamic parameter count, so we can't ** tell if sufficient parameters have been provided). ** 4-Aug-03 (gordy) ** Created neew result-set class for updatable cursors. ** 20-Aug-03 (gordy) ** Send AUTO_CLOSE flag for query statements. ** 6-Oct-03 (gordy) ** Fetch first block of rows for read-only cursors. ** 1-Nov-03 (gordy) ** Implemented updatable result-sets. ParamSet now ** builds DESC/DATA messages. */ private void exec( ParamSet param_set ) { int param_cnt; clearResults(); /* ** All dynamic parameters must be set. We check that all ** contiguous parameters have been set, the DBMS will check ** that sufficient parameters have been provided. */ param_cnt = param_set.getCount(); for( int param = 0; param < param_cnt; param++ ) if ( ! param_set.isSet( param ) ) { if ( trace.enabled( 1 ) ) trace.write( tr_id + ": parameter not set: " + (param + 1) ); throw SqlEx.get( ERR_GC4020_NO_PARAM ); } /* ** Is the current driver transaction ID different ** than the ID obtained when the query was prepared? ** If so, the prepared statement was lost with the ** change in transaction state and we need to prepare ** the query again. */ if ( xactID != conn.getXactID() ) prepare(); msg.LockConnection(); try { if ( prepRSMD == null ) { /* ** Non-query statement (execute). */ msg.begin( MSG_QUERY ); msg.write( MSG_QRY_EXS ); msg.write( MSG_QP_STMT_NAME ); msg.write( stmt_name ); msg.done( (param_cnt <= 0) ); if ( param_cnt > 0 ) { param_set.sendDesc(false); param_set.sendData(true); } readResults( timeout, true ); } else { /* ** Select statement (open a cursor). Generate a ** cursor ID if not provided by the application. */ int concurrency = getConcurrency( qry_concur ); short flags = 0; bool needEOG = true; String stmt = stmt_name; String cursor = (crsr_name != null) ? crsr_name : conn.getUniqueID( crsr_prefix ); /* ** Parser removes FOR READONLY clause because it isn't ** a part of Ingres SELECT syntax. Tell server that ** cursor should be READONLY (kludge older protocol ** by appending clause to statement name). */ if ( concurrency == DrvConst.DRV_CRSR_READONLY ) if ( conn.msg_protocol_level < MSG_PROTO_2 ) stmt += " for readonly"; else if ( conn.msg_protocol_level < MSG_PROTO_3 ) flags = (short)(flags | MSG_QF_READONLY); else { flags = (short)(flags | MSG_QF_READONLY | MSG_QF_FETCH_FIRST); needEOG = false; } if ( conn.msg_protocol_level >= MSG_PROTO_3 ) flags = (short)(flags | MSG_QF_AUTO_CLOSE); msg.begin( MSG_QUERY ); msg.write( MSG_QRY_OCS ); if ( flags != 0 ) { msg.write( MSG_QP_FLAGS ); msg.write( (short)2 ); msg.write( flags ); } msg.write( MSG_QP_CRSR_NAME ); msg.write( cursor ); msg.write( MSG_QP_STMT_NAME ); msg.write( stmt ); msg.done( (param_cnt <= 0) ); if ( param_cnt > 0 ) { param_set.sendDesc(false); param_set.sendData(true); } /* ** Check to see if a new result-set descriptor ** has been received. If so, it may be different ** than the previous descriptor and will be more ** accurate (save only if present). */ AdvanRSMD rsmd = readResults( timeout, needEOG ); if ( rsmd != null ) prepRSMD = rsmd; /* ** The cursor name is passed to the result-set ** for updatable cursors or if provided by the ** application (2.1 API spec). */ if ( (rslt_flags & MSG_RF_READ_ONLY) == 0 ) { resultSet = new RsltUpd( conn, this, rsmd, rslt_val_stmt, cursor ); if ( msg.moreMessages() ) readResults( timeout, true ); } else { if ( rs_concur == DrvConst.DRV_CRSR_UPDATE ) warnings.Add( SqlEx.get( ERR_GC4016_RS_CHANGED )); resultSet = new RsltCurs( conn, this, rsmd, rslt_val_stmt, crsr_name, getPreFetchSize(), msg.moreMessages() ); } } } catch( SqlEx ex ) { if ( trace.enabled() ) trace.log( title + ".execute(): error executing query" ); if ( trace.enabled( 1 ) ) ex.trace( trace ); throw ex; } finally { msg.UnlockConnection(); } return; }
/* ** Name: AdvanPrep ** ** Description: ** Class constructor. Common functionality for this class ** and derived classes which don't actually prepare the ** SQL text. ** ** Input: ** conn Associated connection. ** rs_type Default ResultSet type. ** rs_concur Cursor concurrency. ** rs_hold Default ResultSet holdability. ** ** Output: ** None. ** ** History: ** 13-Jun-00 (gordy) ** Created. ** 1-Nov-00 (gordy) ** Changed parameters for 2.0 extensions. ** 8-Jan-01 (gordy) ** Set max varchar length in parameter set. ** 31-Oct-02 (gordy) ** Added max lengths for other column types. ** 19-Feb-03 (gordy) ** Added ResultSet holdability. Pass CharSet to ParamSet. ** 12-Sep-03 (gordy) ** Replaced timezones with GMT indicator and SqlDates utility. ** 1-Nov-03 (gordy) ** ParamSet funtionality extended. Moved column lengths to DrvConn. */ protected AdvanPrep( DrvConn conn, int rs_type, int rs_concur, int rs_hold ) : base(conn, rs_type, rs_concur, rs_hold) { paramSet = new ParamSet(conn); parameterMarkers = new StringCollection(); return; }
/* ** Name: addBatch ** ** Description: ** Add parameters to batch set. ** ** Input: ** None. ** ** Output: ** None. ** ** Returns: ** void. ** ** History: ** 11-Jan-01 (gordy) ** Created. ** 23-Jan-01 (gordy) ** Allocate batch list on first access. ** 31-Oct-02 (gordy) ** Super-class now provides newBatch() to initialize batch list. ** 1-Nov-03 (gordy) ** ParamSet no longer clonable. Save current and alloc new. */ internal virtual void addBatch() { if ( trace.enabled() ) trace.log( title + ".addBatch()" ); if ( prepRSMD != null ) { if ( trace.enabled() ) trace.log( title + ".addBatch(): statement is a query" ); throw SqlEx.get( ERR_GC4018_RESULT_SET_NOT_PERMITTED ); } if ( batch == null ) newBatch(); lock( batch ) { batch.Add( paramSet ); paramSet = new ParamSet(conn); } return; }