private void Execute() { /* * Common code for ExecuteNonQuery and ExecuteReader. */ // There must be a valid and open connection. if (_connection == null || _connection.State != ConnectionState.Open) throw new InvalidOperationException("Connection must valid and open"); // if a DataReader is open then connection is too busy for anything else CheckIfDataReaderAlreadyOpen(); // set transaction context, autocommit/manualcommit, isolation level SetTransactionContext(); // if need to force a re-Prepare because CommandText changed if (forceRePrepare) { forceRePrepare = false; // no longer need to force a re-Prepare if (advanStmt != null) // close and clear { advanStmt.close(); advanStmt = null; } } // end if (forceRePrepare) AdvanCall advanCall = null; AdvanPrep advanPrep = null; int paramCount; if (Parameters != null && Parameters.Count > 0) paramCount = Parameters.Count; else paramCount = 0; if (this.isaProcedureCall()) { string callSyntaxString = this.BuildCallProcedureSyntax(); try { advanCall = _connection.advanConnect.prepareCall( callSyntaxString ); } catch( SqlEx ex ) { throw ex.createProviderException(); } advanStmt = advanCall; // advanStmt -> AdvanStmt obj } else // not a procedure call { // if we have parameters then we must internally prepare the command. if (paramCount > 0) // If not already prepared, prepare the command // since we need to pass parameters. // If already prepared then advanStmt has an AdvanPrep object. if (advanStmt == null || advanStmt as AdvanPrep == null) PrepareStmt(); // Build the statement as a prepared stmt. // advanStmt -> AdvanStmt obj } try { if (advanStmt == null) // if not AdvanCall nor AdvanPrep then AdvanStmt advanStmt = _connection.advanConnect.createStatement(); else advanPrep = advanStmt as AdvanPrep; // prepared execution? } catch( SqlEx ex ) { throw ex.createProviderException(); } // if parameter list present then build up ParamSet. // default the parameter list to the // existing command.Parameters collection. IngresParameterCollection parameters = Parameters; if (paramCount > 0) { // if named parameter markers are being used // rebuild the parameter list in the order of the markers. StringCollection parameterMarkers = advanPrep.parameterMarkers; if (parameterMarkers.Count > 0 && // rebuild if "?myparm", parameterMarkers[0].Length > 1) // but not if "?" { parameters = new IngresParameterCollection(); // Try to match "?myparm" or "myparm" against the // IngresCommand.Parameters collection and // re-order it into a new parameter collection. foreach (String parameterMarker in parameterMarkers) { string marker = parameterMarker; // look for "?myparm" if (Parameters.Contains(marker) == false) { if (marker.Length > 1) // instead of "?myparm" marker = marker.Substring(1); // try "myparm" if (Parameters.Contains(marker) == false) throw new SqlEx( "Named parameter marker \"" + parameterMarker + "\" " + "was not found in the IngresCommand.Parameters " + "collection."); } IngresParameter parm = Parameters[marker]; parameters.Add(parm.Clone()); } // end foreach (String parameterMarker in Markers) } // endif Markers.Count > 0 && Markers[0].Length > 1 int paramIndex = -1; foreach(IngresParameter parm in parameters) { paramIndex++; // if Output or ReturnValue parm then there is no value yet. if (parm.Direction == ParameterDirection.ReturnValue) continue; else if (parm.Direction == ParameterDirection.Output) { if (advanCall != null) advanCall.registerOutParameter(paramIndex, parm.ProviderType); continue; } else if (parm.Direction == ParameterDirection.InputOutput) { if (advanCall != null) advanCall.registerOutParameter(paramIndex, parm.ProviderType); // fall through to send out the Input value } if (parm.Value == null) { string parmName = parm.ParameterName; if (parmName == null) parmName = ""; string msg = "Parameter '{0}' in ParameterCollection " + "at index {1} has Parameter.Value equal to null. " + "Set Parameter.Value equal to DBNull.Value " + "if sending a null parameter to the database."; throw new IngresException( String.Format(msg, parmName, paramIndex)); } try { if (Convert.IsDBNull(parm.Value)) advanPrep.setNull( paramIndex, ProviderType.DBNull); else advanPrep.setObject( paramIndex, parm.Value, parm.ProviderType, parm.Scale, parm.Size); } catch( SqlEx ex ) { throw ex.createProviderException(); } } } // Execute the command, prepared command, or call procedure try { if (advanCall != null) { advanCall.execute(); // call procedure // if parms are present, check for Return Value parm if (this.Parameters.Count > 0) { int procRsltIndex = -1; // Result param index if (this.Parameters[0].Direction == ParameterDirection.ReturnValue) procRsltIndex = 0; else if (this.Parameters[this.Parameters.Count-1].Direction == ParameterDirection.ReturnValue) procRsltIndex = this.Parameters.Count-1; // if ReturnValue is in parm list, set the value in parm if (procRsltIndex >= 0) { object obj = advanCall.getObject(procRsltIndex); try { Type type = ProviderTypeMgr.GetNETType( this.Parameters[procRsltIndex].ProviderType); // if DbType == Byte, a better conversion match is Byte if (this.Parameters[procRsltIndex].DbType == DbType.Byte) type = typeof(System.Byte); // if possible, convert to target type if (obj != null ) obj = Convert.ChangeType(obj, type); } catch (InvalidCastException ex) { throw new IngresException( "InvalidCastException thrown while converting "+ "DB procedure return value to target data type " + "as specified by IngresParameter.", ex); } this.Parameters[procRsltIndex].Value = obj; } // if (procRsltIndex >= 0) // retrieve the value for Output and InputOutput parms int i = -1; // parameter index [0:parmcnt-1] foreach(IngresParameter parm in this.Parameters) { i++; // bump up parameter index // skip parm if Input or ReturnValue if (parm.Direction != ParameterDirection.Output && parm.Direction != ParameterDirection.InputOutput) continue; this.Parameters[i].Value = advanCall.getObject(i); // retrieve the output value } // end foreach IngresParameter } // if (this.Parameters.Count > 0) } else if (advanPrep != null) advanPrep.execute(); // execute prepared statement else advanStmt.execute(CommandTextAsBuilt); // execute statement directly } catch( SqlEx ex ) { throw ex.createProviderException(); } FireInfoMessageEvent(); // call the delegates with any warning messages } // Execute
/// <summary> /// Release allocated resources of the Command and base Component. /// </summary> /// <param name="disposing"> /// true if object is being explicitly disposed of, not finalized. /// false if method is called by runtime from inside the finalizer. /// </param> protected override void Dispose(bool disposing) { /*if disposing == true Object is being explicitly disposed of, not finalized if disposing == false then method called by runtime from inside the finalizer and we should not reference other objects. */ lock(this) { try { if (disposing) { Connection = null; _transaction = null; _commandText = null; _parameters = null; advanStmt = null; } } finally { base.Dispose(disposing); // let component base do its cleanup } } }