static internal extern /*SQLRETURN*/ODBC32.RetCode SQLBindCol( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLUSMALLINT*/UInt16 ColumnNumber, /*SQLSMALLINT*/ODBC32.SQL_C TargetType, /*SQLPOINTER*/IntPtr TargetValue, /*SQLLEN*/IntPtr BufferLength, /*SQLLEN* */IntPtr StrLen_or_Ind);
internal OdbcHandle(OdbcStatementHandle parentHandle, ODBC32.SQL_ATTR attribute) : base(IntPtr.Zero, true) { ODBC32.RetCode code; this._handleType = ODBC32.SQL_HANDLE.DESC; bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { int num; parentHandle.DangerousAddRef(ref success); code = parentHandle.GetStatementAttribute(attribute, out this.handle, out num); } finally { if (success) { if (IntPtr.Zero != base.handle) { this._parentHandle = parentHandle; } else { parentHandle.DangerousRelease(); } } } if (ADP.PtrZero == base.handle) { throw ODBC.FailedToGetDescriptorHandle(code); } }
internal void FreeStatementHandle(ODBC32.STMT stmt) { DisposeDescriptorHandle(); OdbcStatementHandle handle = _stmt; if (null != handle) { try { ODBC32.RetCode retcode; retcode = handle.FreeStatement(stmt); StatementErrorHandler(retcode); } catch (Exception e) { // if (ADP.IsCatchableExceptionType(e)) { _stmt = null; handle.Dispose(); } throw; } } }
// OdbcCommand.Cancel() // // In ODBC3.0 ... a call to SQLCancel when no processing is done has no effect at all // (ODBC Programmer's Reference ...) // public override void Cancel() { CMDWrapper wrapper = _cmdWrapper; if (null != wrapper) { wrapper.Canceling = true; OdbcStatementHandle stmt = wrapper.StatementHandle; if (null != stmt) { lock (stmt) { // Cancel the statement ODBC32.RetCode retcode = stmt.Cancel(); // copy of StatementErrorHandler, because stmt may become null switch (retcode) { case ODBC32.RetCode.SUCCESS: case ODBC32.RetCode.SUCCESS_WITH_INFO: // don't fire info message events on cancel break; default: throw wrapper.Connection.HandleErrorNoThrow(stmt, retcode); } } } } }
// Prepare // // if the CommandType property is set to TableDirect Prepare does nothing. // if the CommandType property is set to StoredProcedure Prepare should succeed but result // in a no-op // // throw InvalidOperationException // if the connection is not set // if the connection is not open // public override void Prepare() { ODBC32.RetCode retcode; ValidateOpenConnection(ADP.Prepare); if (0 != (ConnectionState.Fetching & _connection.InternalState)) { throw ADP.OpenReaderExists(); } if (CommandType == CommandType.TableDirect) { return; // do nothing } DisposeDeadDataReader(); GetStatementHandle(); OdbcStatementHandle stmt = _cmdWrapper.StatementHandle; retcode = stmt.Prepare(CommandText); if (ODBC32.RetCode.SUCCESS != retcode) { _connection.HandleError(stmt, retcode); } _isPrepared = true; }
private static OdbcParameter[] DeriveParametersFromStoredProcedure(OdbcConnection connection, OdbcCommand command) { List <OdbcParameter> list = new List <OdbcParameter>(); CMDWrapper statementHandle = command.GetStatementHandle(); OdbcStatementHandle hrHandle = statementHandle.StatementHandle; string leftQuote = connection.QuoteChar("DeriveParameters"); string[] strArray = MultipartIdentifier.ParseMultipartIdentifier(command.CommandText, leftQuote, leftQuote, '.', 4, true, "ODBC_ODBCCommandText", false); if (strArray[3] == null) { strArray[3] = command.CommandText; } ODBC32.RetCode retcode = hrHandle.ProcedureColumns(strArray[1], strArray[2], strArray[3], null); if (retcode != ODBC32.RetCode.SUCCESS) { connection.HandleError(hrHandle, retcode); } using (OdbcDataReader reader = new OdbcDataReader(command, statementHandle, CommandBehavior.Default)) { reader.FirstResult(); int fieldCount = reader.FieldCount; while (reader.Read()) { OdbcParameter item = new OdbcParameter { ParameterName = reader.GetString(3) }; switch (reader.GetInt16(4)) { case 1: item.Direction = ParameterDirection.Input; break; case 2: item.Direction = ParameterDirection.InputOutput; break; case 4: item.Direction = ParameterDirection.Output; break; case 5: item.Direction = ParameterDirection.ReturnValue; break; } item.OdbcType = TypeMap.FromSqlType((ODBC32.SQL_TYPE)reader.GetInt16(5))._odbcType; item.Size = reader.GetInt32(7); switch (item.OdbcType) { case OdbcType.Decimal: case OdbcType.Numeric: item.ScaleInternal = (byte)reader.GetInt16(9); item.PrecisionInternal = (byte)reader.GetInt16(10); break; } list.Add(item); } } retcode = hrHandle.CloseCursor(); return(list.ToArray()); }
internal void DisposeKeyInfoStatementHandle() { OdbcStatementHandle handle = this._keyinfostmt; if (handle != null) { this._keyinfostmt = null; handle.Dispose(); } }
internal void DisposeKeyInfoStatementHandle() { OdbcStatementHandle handle = _keyinfostmt; if (null != handle) { _keyinfostmt = null; handle.Dispose(); } }
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLBindParameter( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLUSMALLINT*/UInt16 ParameterNumber, /*SQLSMALLINT*/Int16 ParamDirection, /*SQLSMALLINT*/ODBC32.SQL_C SQLCType, /*SQLSMALLINT*/Int16 SQLType, /*SQLULEN*/IntPtr cbColDef, /*SQLSMALLINT*/IntPtr ibScale, /*SQLPOINTER*/HandleRef rgbValue, /*SQLLEN*/IntPtr BufferLength, /*SQLLEN* */HandleRef StrLen_or_Ind);
internal void DisposeStatementHandle() { this.DisposeKeyInfoStatementHandle(); this.DisposeDescriptorHandle(); OdbcStatementHandle handle = this._stmt; if (handle != null) { this._stmt = null; handle.Dispose(); } }
internal void DisposeStatementHandle() { DisposeKeyInfoStatementHandle(); DisposeDescriptorHandle(); OdbcStatementHandle handle = _stmt; if (null != handle) { _stmt = null; handle.Dispose(); } }
private void TrySetStatementAttribute(OdbcStatementHandle stmt, ODBC32.SQL_ATTR stmtAttribute, IntPtr value) { if (stmt.SetStatementAttribute(stmtAttribute, value, ODBC32.SQL_IS.UINTEGER) == ODBC32.RetCode.ERROR) { string str; stmt.GetDiagnosticField(out str); switch (str) { case "HYC00": case "HY092": this.Connection.FlagUnsupportedStmtAttr(stmtAttribute); break; } } }
internal OdbcHandle(OdbcStatementHandle parentHandle, ODBC32.SQL_ATTR attribute) : base(IntPtr.Zero, true) { Debug.Assert((ODBC32.SQL_ATTR.APP_PARAM_DESC == attribute) || (ODBC32.SQL_ATTR.APP_ROW_DESC == attribute), "invalid attribute"); _handleType = ODBC32.SQL_HANDLE.DESC; int cbActual; ODBC32.RetCode retcode; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { // must addref before calling native so it won't be released just after parentHandle.DangerousAddRef(ref mustRelease); retcode = parentHandle.GetStatementAttribute(attribute, out base.handle, out cbActual); } finally { if (mustRelease) { if (IntPtr.Zero != base.handle) { // must call DangerousAddRef after a handle is actually created // since ReleaseHandle will only call DangerousRelease if a handle exists _parentHandle = parentHandle; } else { // without a handle, ReleaseHandle may not be called parentHandle.DangerousRelease(); } } } if (ADP.PtrZero == base.handle) { throw ODBC.FailedToGetDescriptorHandle(retcode); } // no info-message handle on getting a descriptor handle }
public override void Prepare() { OdbcConnection.ExecutePermission.Demand(); this.ValidateOpenConnection("Prepare"); if ((ConnectionState.Fetching & this._connection.InternalState) != ConnectionState.Closed) { throw ADP.OpenReaderExists(); } if (this.CommandType != System.Data.CommandType.TableDirect) { this.DisposeDeadDataReader(); this.GetStatementHandle(); OdbcStatementHandle statementHandle = this._cmdWrapper.StatementHandle; ODBC32.RetCode retcode = statementHandle.Prepare(this.CommandText); if (retcode != ODBC32.RetCode.SUCCESS) { this._connection.HandleError(statementHandle, retcode); } this._isPrepared = true; } }
internal void FreeKeyInfoStatementHandle(ODBC32.STMT stmt) { OdbcStatementHandle handle = this._keyinfostmt; if (handle != null) { try { handle.FreeStatement(stmt); } catch (Exception exception) { if (ADP.IsCatchableExceptionType(exception)) { this._keyinfostmt = null; handle.Dispose(); } throw; } } }
internal void FreeKeyInfoStatementHandle(ODBC32.STMT stmt) { OdbcStatementHandle handle = _keyinfostmt; if (null != handle) { try { handle.FreeStatement(stmt); } catch (Exception e) { // if (ADP.IsCatchableExceptionType(e)) { _keyinfostmt = null; handle.Dispose(); } throw; } } }
private void TrySetStatementAttribute(OdbcStatementHandle stmt, ODBC32.SQL_ATTR stmtAttribute, IntPtr value) { ODBC32.RetCode retcode = stmt.SetStatementAttribute( stmtAttribute, value, ODBC32.SQL_IS.UINTEGER); if (retcode == ODBC32.RetCode.ERROR) { string sqlState; stmt.GetDiagnosticField(out sqlState); if ((sqlState == "HYC00") || (sqlState == "HY092")) { Connection.FlagUnsupportedStmtAttr(stmtAttribute); } else { // now what? Should we throw? } } }
internal void FreeStatementHandle(ODBC32.STMT stmt) { this.DisposeDescriptorHandle(); OdbcStatementHandle handle = this._stmt; if (handle != null) { try { ODBC32.RetCode retcode = handle.FreeStatement(stmt); this.StatementErrorHandler(retcode); } catch (Exception exception) { if (ADP.IsCatchableExceptionType(exception)) { this._stmt = null; handle.Dispose(); } throw; } } }
public override void Cancel() { CMDWrapper wrapper = this._cmdWrapper; if (wrapper != null) { wrapper.Canceling = true; OdbcStatementHandle statementHandle = wrapper.StatementHandle; if (statementHandle != null) { lock (statementHandle) { ODBC32.RetCode retcode = statementHandle.Cancel(); switch (retcode) { case ODBC32.RetCode.SUCCESS: case ODBC32.RetCode.SUCCESS_WITH_INFO: return; } throw wrapper.Connection.HandleErrorNoThrow(statementHandle, retcode); } } } }
internal void CreateStatementHandle() { DisposeStatementHandle(); _stmt = _connection.CreateStatementHandle(); }
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLTablesW ( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, [In, MarshalAs(UnmanagedType.LPWStr)] /*SQLCHAR* */string CatalogName, /*SQLSMALLINT*/Int16 NameLen1, [In, MarshalAs(UnmanagedType.LPWStr)] /*SQLCHAR* */string SchemaName, /*SQLSMALLINT*/Int16 NameLen2, [In, MarshalAs(UnmanagedType.LPWStr)] /*SQLCHAR* */string TableName, /*SQLSMALLINT*/Int16 NameLen3, [In, MarshalAs(UnmanagedType.LPWStr)] /*SQLCHAR* */string TableType, /*SQLSMALLINT*/Int16 NameLen4);
internal OdbcDescriptorHandle(OdbcStatementHandle statementHandle, ODBC32.SQL_ATTR attribute) : base(statementHandle, attribute) { }
internal void CreateKeyInfoStatementHandle() { DisposeKeyInfoStatementHandle(); _keyinfostmt = _connection.CreateStatementHandle(); }
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLColAttributeW ( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLUSMALLINT*/Int16 ColumnNumber, /*SQLUSMALLINT*/Int16 FieldIdentifier, /*SQLPOINTER*/CNativeBuffer CharacterAttribute, /*SQLSMALLINT*/Int16 BufferLength, /*SQLSMALLINT* */out Int16 StringLength, /*SQLPOINTER*/out IntPtr NumericAttribute);
// DeriveParametersFromStoredProcedure ( // OdbcConnection connection, // OdbcCommand command); // // Uses SQLProcedureColumns to create an array of OdbcParameters // static private OdbcParameter[] DeriveParametersFromStoredProcedure(OdbcConnection connection, OdbcCommand command) { List <OdbcParameter> rParams = new List <OdbcParameter>(); // following call ensures that the command has a statement handle allocated CMDWrapper cmdWrapper = command.GetStatementHandle(); OdbcStatementHandle hstmt = cmdWrapper.StatementHandle; int cColsAffected; // maps an enforced 4-part qualified string as follows // parts[0] = null - ignored but removal would be a run-time breaking change from V1.0 // parts[1] = CatalogName (optional, may be null) // parts[2] = SchemaName (optional, may be null) // parts[3] = ProcedureName // string quote = connection.QuoteChar(ADP.DeriveParameters); string[] parts = MultipartIdentifier.ParseMultipartIdentifier(command.CommandText, quote, quote, '.', 4, true, Res.ODBC_ODBCCommandText, false); if (null == parts[3]) { // match Everett behavior, if the commandtext is nothing but whitespace set the command text to the whitespace parts[3] = command.CommandText; } // note: native odbc appears to ignore all but the procedure name ODBC32.RetCode retcode = hstmt.ProcedureColumns(parts[1], parts[2], parts[3], null); // Note: the driver does not return an error if the given stored procedure does not exist // therefore we cannot handle that case and just return not parameters. if (ODBC32.RetCode.SUCCESS != retcode) { connection.HandleError(hstmt, retcode); } using (OdbcDataReader reader = new OdbcDataReader(command, cmdWrapper, CommandBehavior.Default)) { reader.FirstResult(); cColsAffected = reader.FieldCount; // go through the returned rows and filter out relevant parameter data // while (reader.Read()) { // devnote: column types are specified in the ODBC Programmer's Reference // COLUMN_TYPE Smallint 16bit // COLUMN_SIZE Integer 32bit // DECIMAL_DIGITS Smallint 16bit // NUM_PREC_RADIX Smallint 16bit OdbcParameter parameter = new OdbcParameter(); parameter.ParameterName = reader.GetString(ODBC32.COLUMN_NAME - 1); switch ((ODBC32.SQL_PARAM)reader.GetInt16(ODBC32.COLUMN_TYPE - 1)) { case ODBC32.SQL_PARAM.INPUT: parameter.Direction = ParameterDirection.Input; break; case ODBC32.SQL_PARAM.OUTPUT: parameter.Direction = ParameterDirection.Output; break; case ODBC32.SQL_PARAM.INPUT_OUTPUT: parameter.Direction = ParameterDirection.InputOutput; break; case ODBC32.SQL_PARAM.RETURN_VALUE: parameter.Direction = ParameterDirection.ReturnValue; break; default: Debug.Assert(false, "Unexpected Parametertype while DeriveParamters"); break; } parameter.OdbcType = TypeMap.FromSqlType((ODBC32.SQL_TYPE)reader.GetInt16(ODBC32.DATA_TYPE - 1))._odbcType; parameter.Size = (int)reader.GetInt32(ODBC32.COLUMN_SIZE - 1); switch (parameter.OdbcType) { case OdbcType.Decimal: case OdbcType.Numeric: parameter.ScaleInternal = (Byte)reader.GetInt16(ODBC32.DECIMAL_DIGITS - 1); parameter.PrecisionInternal = (Byte)reader.GetInt16(ODBC32.NUM_PREC_RADIX - 1); break; } rParams.Add(parameter); } } retcode = hstmt.CloseCursor(); return(rParams.ToArray());; }
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLGetData( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLUSMALLINT*/UInt16 ColumnNumber, /*SQLSMALLINT*/ODBC32.SQL_C TargetType, /*SQLPOINTER*/CNativeBuffer TargetValue, /*SQLLEN*/IntPtr BufferLength, // sql.h differs from MSDN /*SQLLEN* */out IntPtr StrLen_or_Ind);
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLFreeStmt( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLUSMALLINT*/ODBC32.STMT Option);
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLCancel( /*SQLHSTMT*/OdbcStatementHandle StatementHandle);
internal void CreateStatementHandle() { this.DisposeStatementHandle(); this._stmt = this._connection.CreateStatementHandle(); }
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLCloseCursor( /*SQLHSTMT*/OdbcStatementHandle StatementHandle);
private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, string method, bool needReader, object[] methodArguments, ODBC32.SQL_API odbcApiMethod) { OdbcDataReader target = null; try { ODBC32.RetCode typeInfo; this.DisposeDeadDataReader(); this.ValidateConnectionAndTransaction(method); if ((CommandBehavior.SingleRow & behavior) != CommandBehavior.Default) { behavior |= CommandBehavior.SingleResult; } OdbcStatementHandle statementHandle = this.GetStatementHandle().StatementHandle; this._cmdWrapper.Canceling = false; if ((this.weakDataReaderReference != null) && this.weakDataReaderReference.IsAlive) { object obj2 = this.weakDataReaderReference.Target; if (((obj2 != null) && this.weakDataReaderReference.IsAlive) && !((OdbcDataReader)obj2).IsClosed) { throw ADP.OpenReaderExists(); } } target = new OdbcDataReader(this, this._cmdWrapper, behavior); if (!this.Connection.ProviderInfo.NoQueryTimeout) { this.TrySetStatementAttribute(statementHandle, ODBC32.SQL_ATTR.QUERY_TIMEOUT, (IntPtr)this.CommandTimeout); } if ((needReader && this.Connection.IsV3Driver) && (!this.Connection.ProviderInfo.NoSqlSoptSSNoBrowseTable && !this.Connection.ProviderInfo.NoSqlSoptSSHiddenColumns)) { if (target.IsBehavior(CommandBehavior.KeyInfo)) { if (!this._cmdWrapper._ssKeyInfoModeOn) { this.TrySetStatementAttribute(statementHandle, (ODBC32.SQL_ATTR) 0x4cc, (IntPtr)1L); this.TrySetStatementAttribute(statementHandle, ODBC32.SQL_ATTR.SQL_COPT_SS_TXN_ISOLATION, (IntPtr)1L); this._cmdWrapper._ssKeyInfoModeOff = false; this._cmdWrapper._ssKeyInfoModeOn = true; } } else if (!this._cmdWrapper._ssKeyInfoModeOff) { this.TrySetStatementAttribute(statementHandle, (ODBC32.SQL_ATTR) 0x4cc, (IntPtr)0L); this.TrySetStatementAttribute(statementHandle, ODBC32.SQL_ATTR.SQL_COPT_SS_TXN_ISOLATION, (IntPtr)0L); this._cmdWrapper._ssKeyInfoModeOff = true; this._cmdWrapper._ssKeyInfoModeOn = false; } } if (target.IsBehavior(CommandBehavior.KeyInfo) || target.IsBehavior(CommandBehavior.SchemaOnly)) { typeInfo = statementHandle.Prepare(this.CommandText); if (typeInfo != ODBC32.RetCode.SUCCESS) { this._connection.HandleError(statementHandle, typeInfo); } } bool success = false; CNativeBuffer parameterBuffer = this._cmdWrapper._nativeParameterBuffer; RuntimeHelpers.PrepareConstrainedRegions(); try { if ((this._parameterCollection != null) && (0 < this._parameterCollection.Count)) { int initialSize = this._parameterCollection.CalcParameterBufferSize(this); if ((parameterBuffer == null) || (parameterBuffer.Length < initialSize)) { if (parameterBuffer != null) { parameterBuffer.Dispose(); } parameterBuffer = new CNativeBuffer(initialSize); this._cmdWrapper._nativeParameterBuffer = parameterBuffer; } else { parameterBuffer.ZeroMemory(); } parameterBuffer.DangerousAddRef(ref success); this._parameterCollection.Bind(this, this._cmdWrapper, parameterBuffer); } if (target.IsBehavior(CommandBehavior.SchemaOnly)) { goto Label_0443; } if ((target.IsBehavior(CommandBehavior.KeyInfo) || target.IsBehavior(CommandBehavior.SchemaOnly)) && (this.CommandType != System.Data.CommandType.StoredProcedure)) { short num2; typeInfo = statementHandle.NumberOfResultColumns(out num2); switch (typeInfo) { case ODBC32.RetCode.SUCCESS: case ODBC32.RetCode.SUCCESS_WITH_INFO: if (num2 > 0) { target.GetSchemaTable(); } goto Label_029A; } if (typeInfo != ODBC32.RetCode.NO_DATA) { this._connection.HandleError(statementHandle, typeInfo); } } Label_029A: switch (odbcApiMethod) { case ODBC32.SQL_API.SQLEXECDIRECT: if (target.IsBehavior(CommandBehavior.KeyInfo) || this._isPrepared) { typeInfo = statementHandle.Execute(); } else { typeInfo = statementHandle.ExecuteDirect(this.CommandText); } break; case ODBC32.SQL_API.SQLCOLUMNS: typeInfo = statementHandle.Columns((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (string)methodArguments[3]); break; case ODBC32.SQL_API.SQLSTATISTICS: typeInfo = statementHandle.Statistics((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (short)methodArguments[3], (short)methodArguments[4]); break; case ODBC32.SQL_API.SQLTABLES: typeInfo = statementHandle.Tables((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (string)methodArguments[3]); break; case ODBC32.SQL_API.SQLGETTYPEINFO: typeInfo = statementHandle.GetTypeInfo((short)methodArguments[0]); break; case ODBC32.SQL_API.SQLPROCEDURECOLUMNS: typeInfo = statementHandle.ProcedureColumns((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (string)methodArguments[3]); break; case ODBC32.SQL_API.SQLPROCEDURES: typeInfo = statementHandle.Procedures((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2]); break; default: throw ADP.InvalidOperation(method.ToString()); } if ((typeInfo != ODBC32.RetCode.SUCCESS) && (ODBC32.RetCode.NO_DATA != typeInfo)) { this._connection.HandleError(statementHandle, typeInfo); } } finally { if (success) { parameterBuffer.DangerousRelease(); } } Label_0443: this.weakDataReaderReference = new WeakReference(target); if (!target.IsBehavior(CommandBehavior.SchemaOnly)) { target.FirstResult(); } this.cmdState = ConnectionState.Fetching; } finally { if (ConnectionState.Fetching != this.cmdState) { if (target != null) { if (this._parameterCollection != null) { this._parameterCollection.ClearBindings(); } target.Dispose(); } if (this.cmdState != ConnectionState.Closed) { this.cmdState = ConnectionState.Closed; } } } return(target); }
internal void Bind(OdbcStatementHandle hstmt, OdbcCommand command, short ordinal, CNativeBuffer parameterBuffer, bool allowReentrance) { ODBC32.SQL_C sql_c = this._prepared_Sql_C_Type; ODBC32.SQL_PARAM sql_param = this.SqlDirectionFromParameterDirection(); int offset = this._preparedOffset; int sizeorprecision = this._preparedSize; object obj2 = this._preparedValue; int valueSize = this.GetValueSize(obj2, offset); int num4 = this.GetColumnSize(obj2, offset, ordinal); byte parameterPrecision = this.GetParameterPrecision(obj2); byte parameterScale = this.GetParameterScale(obj2); HandleRef buffer = parameterBuffer.PtrOffset(this._preparedValueOffset, this._preparedBufferSize); HandleRef intbuffer = parameterBuffer.PtrOffset(this._preparedIntOffset, IntPtr.Size); if (ODBC32.SQL_C.NUMERIC == sql_c) { if (((ODBC32.SQL_PARAM.INPUT_OUTPUT == sql_param) && (obj2 is decimal)) && (parameterScale < this._internalScale)) { while (parameterScale < this._internalScale) { obj2 = ((decimal) obj2) * 10M; parameterScale = (byte) (parameterScale + 1); } } this.SetInputValue(obj2, sql_c, valueSize, parameterPrecision, 0, parameterBuffer); if (ODBC32.SQL_PARAM.INPUT != sql_param) { parameterBuffer.WriteInt16(this._preparedValueOffset, (short) ((parameterScale << 8) | parameterPrecision)); } } else { this.SetInputValue(obj2, sql_c, valueSize, sizeorprecision, offset, parameterBuffer); } if (((this._hasChanged || (this._boundSqlCType != sql_c)) || ((this._boundParameterType != this._bindtype._sql_type) || (this._boundSize != num4))) || (((this._boundScale != parameterScale) || (this._boundBuffer != buffer.Handle)) || (this._boundIntbuffer != intbuffer.Handle))) { ODBC32.RetCode retcode = hstmt.BindParameter(ordinal, (short) sql_param, sql_c, this._bindtype._sql_type, (IntPtr) num4, (IntPtr) parameterScale, buffer, (IntPtr) this._preparedBufferSize, intbuffer); if (retcode != ODBC32.RetCode.SUCCESS) { if ("07006" == command.GetDiagSqlState()) { Bid.Trace("<odbc.OdbcParameter.Bind|ERR> Call to BindParameter returned errorcode [07006]\n"); command.Connection.FlagRestrictedSqlBindType(this._bindtype._sql_type); if (allowReentrance) { this.Bind(hstmt, command, ordinal, parameterBuffer, false); return; } } command.Connection.HandleError(hstmt, retcode); } this._hasChanged = false; this._boundSqlCType = sql_c; this._boundParameterType = this._bindtype._sql_type; this._boundSize = num4; this._boundScale = parameterScale; this._boundBuffer = buffer.Handle; this._boundIntbuffer = intbuffer.Handle; if (ODBC32.SQL_C.NUMERIC == sql_c) { OdbcDescriptorHandle descriptorHandle = command.GetDescriptorHandle(ODBC32.SQL_ATTR.APP_PARAM_DESC); retcode = descriptorHandle.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.TYPE, (IntPtr) 2L); if (retcode != ODBC32.RetCode.SUCCESS) { command.Connection.HandleError(hstmt, retcode); } int num2 = parameterPrecision; retcode = descriptorHandle.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.PRECISION, (IntPtr) num2); if (retcode != ODBC32.RetCode.SUCCESS) { command.Connection.HandleError(hstmt, retcode); } num2 = parameterScale; retcode = descriptorHandle.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.SCALE, (IntPtr) num2); if (retcode != ODBC32.RetCode.SUCCESS) { command.Connection.HandleError(hstmt, retcode); } retcode = descriptorHandle.SetDescriptionField2(ordinal, ODBC32.SQL_DESC.DATA_PTR, buffer); if (retcode != ODBC32.RetCode.SUCCESS) { command.Connection.HandleError(hstmt, retcode); } } } }
private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, string method, bool needReader, object[] methodArguments, ODBC32.SQL_API odbcApiMethod) { // MDAC 68324 OdbcDataReader localReader = null; try { DisposeDeadDataReader(); // this is a no-op if cmdState is not Fetching ValidateConnectionAndTransaction(method); // cmdState will change to Executing if (0 != (CommandBehavior.SingleRow & behavior)) { // CommandBehavior.SingleRow implies CommandBehavior.SingleResult behavior |= CommandBehavior.SingleResult; } ODBC32.RetCode retcode; OdbcStatementHandle stmt = GetStatementHandle().StatementHandle; _cmdWrapper.Canceling = false; if (null != _weakDataReaderReference) { if (_weakDataReaderReference.IsAlive) { object target = _weakDataReaderReference.Target; if (null != target && _weakDataReaderReference.IsAlive) { if (!((OdbcDataReader)target).IsClosed) { throw ADP.OpenReaderExists(); // MDAC 66411 } } } } localReader = new OdbcDataReader(this, _cmdWrapper, behavior); //Set command properties //Not all drivers support timeout. So fail silently if error if (!Connection.ProviderInfo.NoQueryTimeout) { TrySetStatementAttribute(stmt, ODBC32.SQL_ATTR.QUERY_TIMEOUT, (IntPtr)this.CommandTimeout); } // todo: If we remember the state we can omit a lot of SQLSetStmtAttrW calls ... // if we do not create a reader we do not even need to do that if (needReader) { if (Connection.IsV3Driver) { if (!Connection.ProviderInfo.NoSqlSoptSSNoBrowseTable && !Connection.ProviderInfo.NoSqlSoptSSHiddenColumns) { // Need to get the metadata information //SQLServer actually requires browse info turned on ahead of time... //Note: We ignore any failures, since this is SQLServer specific //We won't specialcase for SQL Server but at least for non-V3 drivers if (localReader.IsBehavior(CommandBehavior.KeyInfo)) { if (!_cmdWrapper._ssKeyInfoModeOn) { TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.NOBROWSETABLE, (IntPtr)ODBC32.SQL_NB.ON); TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.HIDDEN_COLUMNS, (IntPtr)ODBC32.SQL_HC.ON); _cmdWrapper._ssKeyInfoModeOff = false; _cmdWrapper._ssKeyInfoModeOn = true; } } else { if (!_cmdWrapper._ssKeyInfoModeOff) { TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.NOBROWSETABLE, (IntPtr)ODBC32.SQL_NB.OFF); TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.HIDDEN_COLUMNS, (IntPtr)ODBC32.SQL_HC.OFF); _cmdWrapper._ssKeyInfoModeOff = true; _cmdWrapper._ssKeyInfoModeOn = false; } } } } } if (localReader.IsBehavior(CommandBehavior.KeyInfo) || localReader.IsBehavior(CommandBehavior.SchemaOnly)) { retcode = stmt.Prepare(CommandText); if (ODBC32.RetCode.SUCCESS != retcode) { _connection.HandleError(stmt, retcode); } } bool mustRelease = false; CNativeBuffer parameterBuffer = _cmdWrapper._nativeParameterBuffer; RuntimeHelpers.PrepareConstrainedRegions(); try { //Handle Parameters //Note: We use the internal variable as to not instante a new object collection, //for the common case of using no parameters. if ((null != _parameterCollection) && (0 < _parameterCollection.Count)) { int parameterBufferSize = _parameterCollection.CalcParameterBufferSize(this); if (null == parameterBuffer || parameterBuffer.Length < parameterBufferSize) { if (null != parameterBuffer) { parameterBuffer.Dispose(); } parameterBuffer = new CNativeBuffer(parameterBufferSize); _cmdWrapper._nativeParameterBuffer = parameterBuffer; } else { parameterBuffer.ZeroMemory(); } parameterBuffer.DangerousAddRef(ref mustRelease); _parameterCollection.Bind(this, _cmdWrapper, parameterBuffer); } if (!localReader.IsBehavior(CommandBehavior.SchemaOnly)) { // Can't get the KeyInfo after command execution (SQL Server only since it does not support multiple // results on the same connection). Stored procedures (SP) do not return metadata before actual execution // Need to check the column count since the command type may not be set to SP for a SP. if ((localReader.IsBehavior(CommandBehavior.KeyInfo) || localReader.IsBehavior(CommandBehavior.SchemaOnly)) && (CommandType != CommandType.StoredProcedure)) { short cColsAffected; retcode = stmt.NumberOfResultColumns(out cColsAffected); if (retcode == ODBC32.RetCode.SUCCESS || retcode == ODBC32.RetCode.SUCCESS_WITH_INFO) { if (cColsAffected > 0) { localReader.GetSchemaTable(); } } else if (retcode == ODBC32.RetCode.NO_DATA) { // do nothing } else { // any other returncode indicates an error _connection.HandleError(stmt, retcode); } } switch (odbcApiMethod) { case ODBC32.SQL_API.SQLEXECDIRECT: if (localReader.IsBehavior(CommandBehavior.KeyInfo) || _isPrepared) { //Already prepared, so use SQLExecute retcode = stmt.Execute(); // Build metadata here // localReader.GetSchemaTable(); } else { #if DEBUG //if (AdapterSwitches.OleDbTrace.TraceInfo) { // ADP.DebugWriteLine("SQLExecDirectW: " + CommandText); //} #endif //SQLExecDirect retcode = stmt.ExecuteDirect(CommandText); } break; case ODBC32.SQL_API.SQLTABLES: retcode = stmt.Tables((string)methodArguments[0], //TableCatalog (string)methodArguments[1], //TableSchema, (string)methodArguments[2], //TableName (string)methodArguments[3]); //TableType break; case ODBC32.SQL_API.SQLCOLUMNS: retcode = stmt.Columns((string)methodArguments[0], //TableCatalog (string)methodArguments[1], //TableSchema (string)methodArguments[2], //TableName (string)methodArguments[3]); //ColumnName break; case ODBC32.SQL_API.SQLPROCEDURES: retcode = stmt.Procedures((string)methodArguments[0], //ProcedureCatalog (string)methodArguments[1], //ProcedureSchema (string)methodArguments[2]); //procedureName break; case ODBC32.SQL_API.SQLPROCEDURECOLUMNS: retcode = stmt.ProcedureColumns((string)methodArguments[0], //ProcedureCatalog (string)methodArguments[1], //ProcedureSchema (string)methodArguments[2], //procedureName (string)methodArguments[3]); //columnName break; case ODBC32.SQL_API.SQLSTATISTICS: retcode = stmt.Statistics((string)methodArguments[0], //TableCatalog (string)methodArguments[1], //TableSchema (string)methodArguments[2], //TableName (short)methodArguments[3], //IndexTrpe (short)methodArguments[4]); //Accuracy break; case ODBC32.SQL_API.SQLGETTYPEINFO: retcode = stmt.GetTypeInfo((short)methodArguments[0]); //SQL Type break; default: // this should NEVER happen Debug.Fail("ExecuteReaderObjectcalled with unsupported ODBC API method."); throw ADP.InvalidOperation(method.ToString()); } //Note: Execute will return NO_DATA for Update/Delete non-row returning queries if ((ODBC32.RetCode.SUCCESS != retcode) && (ODBC32.RetCode.NO_DATA != retcode)) { _connection.HandleError(stmt, retcode); } } // end SchemaOnly } finally { if (mustRelease) { parameterBuffer.DangerousRelease(); } } _weakDataReaderReference = new WeakReference(localReader); // XXXCommand.Execute should position reader on first row returning result // any exceptions in the initial non-row returning results should be thrown // from ExecuteXXX not the DataReader if (!localReader.IsBehavior(CommandBehavior.SchemaOnly)) { localReader.FirstResult(); } _cmdState = ConnectionState.Fetching; } finally { if (ConnectionState.Fetching != _cmdState) { if (null != localReader) { // clear bindings so we don't grab output parameters on a failed execute if (null != _parameterCollection) { _parameterCollection.ClearBindings(); } ((IDisposable)localReader).Dispose(); } if (ConnectionState.Closed != _cmdState) { _cmdState = ConnectionState.Closed; } } } return(localReader); }
internal void Bind(OdbcStatementHandle hstmt, OdbcCommand command, short ordinal, CNativeBuffer parameterBuffer, bool allowReentrance) { ODBC32.RetCode retcode; ODBC32.SQL_C sql_c_type = _prepared_Sql_C_Type; ODBC32.SQL_PARAM sqldirection = SqlDirectionFromParameterDirection(); int offset = _preparedOffset; int size = _preparedSize; object value = _preparedValue; int cbValueSize = GetValueSize(value, offset); // count of bytes for the data int cchSize = GetColumnSize(value, offset, ordinal); // count of bytes for the data, used to allocate the buffer length byte precision = GetParameterPrecision(value); byte scale = GetParameterScale(value); int cbActual; HandleRef valueBuffer = parameterBuffer.PtrOffset(_preparedValueOffset, _preparedBufferSize); HandleRef intBuffer = parameterBuffer.PtrOffset(_preparedIntOffset, IntPtr.Size); // for the numeric datatype we need to do some special case handling ... // if (ODBC32.SQL_C.NUMERIC == sql_c_type) { // for input/output parameters we need to adjust the scale of the input value since the convert function in // sqlsrv32 takes this scale for the output parameter (possible bug in sqlsrv32?) // if ((ODBC32.SQL_PARAM.INPUT_OUTPUT == sqldirection) && (value is Decimal)) { if (scale < _internalScale) { while (scale < _internalScale) { value = ((decimal)value ) * 10; scale++; } } } SetInputValue(value, sql_c_type, cbValueSize, precision, 0, parameterBuffer); // for output parameters we need to write precision and scale to the buffer since the convert function in // sqlsrv32 expects these values there (possible bug in sqlsrv32?) // if (ODBC32.SQL_PARAM.INPUT != sqldirection) { parameterBuffer.WriteInt16(_preparedValueOffset, (short)(((ushort)scale << 8) | (ushort)precision)); } } else { SetInputValue(value, sql_c_type, cbValueSize, size, offset, parameterBuffer); } // Try to reuse existing bindings if // the binding is valid (means we already went through binding all parameters) // the parametercollection is bound already // the bindtype ParameterType did not change (forced upgrade) if (!_hasChanged && (_boundSqlCType == sql_c_type) && (_boundParameterType == _bindtype._sql_type) && (_boundSize == cchSize) && (_boundScale == scale) && (_boundBuffer == valueBuffer.Handle) && (_boundIntbuffer == intBuffer.Handle) ) { return; } //SQLBindParameter retcode = hstmt.BindParameter( ordinal, // Parameter Number (short)sqldirection, // InputOutputType sql_c_type, // ValueType _bindtype._sql_type, // ParameterType (IntPtr)cchSize, // ColumnSize (IntPtr)scale, // DecimalDigits valueBuffer, // ParameterValuePtr (IntPtr)_preparedBufferSize, intBuffer); // StrLen_or_IndPtr if (ODBC32.RetCode.SUCCESS != retcode) { if ("07006" == command.GetDiagSqlState()) { Bid.Trace("<odbc.OdbcParameter.Bind|ERR> Call to BindParameter returned errorcode [07006]\n"); command.Connection.FlagRestrictedSqlBindType(_bindtype._sql_type); if (allowReentrance) { this.Bind(hstmt, command, ordinal, parameterBuffer, false); return; } } command.Connection.HandleError(hstmt, retcode); } _hasChanged = false; _boundSqlCType = sql_c_type; _boundParameterType = _bindtype._sql_type; _boundSize = cchSize; _boundScale = scale; _boundBuffer = valueBuffer.Handle; _boundIntbuffer = intBuffer.Handle; if (ODBC32.SQL_C.NUMERIC == sql_c_type) { OdbcDescriptorHandle hdesc = command.GetDescriptorHandle(ODBC32.SQL_ATTR.APP_PARAM_DESC); // descriptor handle is cached on command wrapper, don't release it // Set descriptor Type // //SQLSetDescField(hdesc, i+1, SQL_DESC_TYPE, (void *)SQL_C_NUMERIC, 0); retcode = hdesc.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.TYPE, (IntPtr)ODBC32.SQL_C.NUMERIC); if (ODBC32.RetCode.SUCCESS != retcode) { command.Connection.HandleError(hstmt, retcode); } // Set precision // cbActual= (int)precision; //SQLSetDescField(hdesc, i+1, SQL_DESC_PRECISION, (void *)precision, 0); retcode = hdesc.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.PRECISION, (IntPtr)cbActual); if (ODBC32.RetCode.SUCCESS != retcode) { command.Connection.HandleError(hstmt, retcode); } // Set scale // // SQLSetDescField(hdesc, i+1, SQL_DESC_SCALE, (void *)llen, 0); cbActual= (int)scale; retcode = hdesc.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.SCALE, (IntPtr)cbActual); if (ODBC32.RetCode.SUCCESS != retcode) { command.Connection.HandleError(hstmt, retcode); } // Set data pointer // // SQLSetDescField(hdesc, i+1, SQL_DESC_DATA_PTR, (void *)&numeric, 0); retcode = hdesc.SetDescriptionField2(ordinal, ODBC32.SQL_DESC.DATA_PTR, valueBuffer); if (ODBC32.RetCode.SUCCESS != retcode) { command.Connection.HandleError(hstmt, retcode); } } }
void TrySetStatementAttribute (OdbcStatementHandle stmt, ODBC32.SQL_ATTR stmtAttribute, IntPtr value) { ODBC32.RetCode retcode = stmt.SetStatementAttribute( stmtAttribute, value, ODBC32.SQL_IS.UINTEGER); if (retcode == ODBC32.RetCode.ERROR) { string sqlState; stmt.GetDiagnosticField(out sqlState); if ((sqlState == "HYC00") || (sqlState == "HY092")) { Connection.FlagUnsupportedStmtAttr(stmtAttribute); } else { // now what? Should we throw? } } }
internal void CreateKeyInfoStatementHandle() { this.DisposeKeyInfoStatementHandle(); this._keyinfostmt = this._connection.CreateStatementHandle(); }
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLSetStmtAttrW( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLINTEGER*/Int32 Attribute, /*SQLPOINTER*/IntPtr Value, /*SQLINTEGER*/Int32 StringLength);
internal void Bind(OdbcStatementHandle hstmt, OdbcCommand command, short ordinal, CNativeBuffer parameterBuffer, bool allowReentrance) { ODBC32.SQL_C sql_c = this._prepared_Sql_C_Type; ODBC32.SQL_PARAM sql_param = this.SqlDirectionFromParameterDirection(); int offset = this._preparedOffset; int sizeorprecision = this._preparedSize; object obj2 = this._preparedValue; int valueSize = this.GetValueSize(obj2, offset); int num4 = this.GetColumnSize(obj2, offset, ordinal); byte parameterPrecision = this.GetParameterPrecision(obj2); byte parameterScale = this.GetParameterScale(obj2); HandleRef buffer = parameterBuffer.PtrOffset(this._preparedValueOffset, this._preparedBufferSize); HandleRef intbuffer = parameterBuffer.PtrOffset(this._preparedIntOffset, IntPtr.Size); if (ODBC32.SQL_C.NUMERIC == sql_c) { if (((ODBC32.SQL_PARAM.INPUT_OUTPUT == sql_param) && (obj2 is decimal)) && (parameterScale < this._internalScale)) { while (parameterScale < this._internalScale) { obj2 = ((decimal)obj2) * 10M; parameterScale = (byte)(parameterScale + 1); } } this.SetInputValue(obj2, sql_c, valueSize, parameterPrecision, 0, parameterBuffer); if (ODBC32.SQL_PARAM.INPUT != sql_param) { parameterBuffer.WriteInt16(this._preparedValueOffset, (short)((parameterScale << 8) | parameterPrecision)); } } else { this.SetInputValue(obj2, sql_c, valueSize, sizeorprecision, offset, parameterBuffer); } if (((this._hasChanged || (this._boundSqlCType != sql_c)) || ((this._boundParameterType != this._bindtype._sql_type) || (this._boundSize != num4))) || (((this._boundScale != parameterScale) || (this._boundBuffer != buffer.Handle)) || (this._boundIntbuffer != intbuffer.Handle))) { ODBC32.RetCode retcode = hstmt.BindParameter(ordinal, (short)sql_param, sql_c, this._bindtype._sql_type, (IntPtr)num4, (IntPtr)parameterScale, buffer, (IntPtr)this._preparedBufferSize, intbuffer); if (retcode != ODBC32.RetCode.SUCCESS) { if ("07006" == command.GetDiagSqlState()) { Bid.Trace("<odbc.OdbcParameter.Bind|ERR> Call to BindParameter returned errorcode [07006]\n"); command.Connection.FlagRestrictedSqlBindType(this._bindtype._sql_type); if (allowReentrance) { this.Bind(hstmt, command, ordinal, parameterBuffer, false); return; } } command.Connection.HandleError(hstmt, retcode); } this._hasChanged = false; this._boundSqlCType = sql_c; this._boundParameterType = this._bindtype._sql_type; this._boundSize = num4; this._boundScale = parameterScale; this._boundBuffer = buffer.Handle; this._boundIntbuffer = intbuffer.Handle; if (ODBC32.SQL_C.NUMERIC == sql_c) { OdbcDescriptorHandle descriptorHandle = command.GetDescriptorHandle(ODBC32.SQL_ATTR.APP_PARAM_DESC); retcode = descriptorHandle.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.TYPE, (IntPtr)2L); if (retcode != ODBC32.RetCode.SUCCESS) { command.Connection.HandleError(hstmt, retcode); } int num2 = parameterPrecision; retcode = descriptorHandle.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.PRECISION, (IntPtr)num2); if (retcode != ODBC32.RetCode.SUCCESS) { command.Connection.HandleError(hstmt, retcode); } num2 = parameterScale; retcode = descriptorHandle.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.SCALE, (IntPtr)num2); if (retcode != ODBC32.RetCode.SUCCESS) { command.Connection.HandleError(hstmt, retcode); } retcode = descriptorHandle.SetDescriptionField2(ordinal, ODBC32.SQL_DESC.DATA_PTR, buffer); if (retcode != ODBC32.RetCode.SUCCESS) { command.Connection.HandleError(hstmt, retcode); } } } }
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLSpecialColumnsW ( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLUSMALLINT*/ODBC32.SQL_SPECIALCOLS IdentifierType, [In, MarshalAs(UnmanagedType.LPWStr)] /*SQLCHAR* */string CatalogName, /*SQLSMALLINT*/Int16 NameLen1, [In, MarshalAs(UnmanagedType.LPWStr)] /*SQLCHAR* */string SchemaName, /*SQLSMALLINT*/Int16 NameLen2, [In, MarshalAs(UnmanagedType.LPWStr)] /*SQLCHAR* */string TableName, /*SQLSMALLINT*/Int16 NameLen3, /*SQLUSMALLINT*/ODBC32.SQL_SCOPE Scope, /*SQLUSMALLINT*/ ODBC32.SQL_NULLABILITY Nullable);
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLGetTypeInfo( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLSMALLINT*/Int16 fSqlType);
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLRowCount( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLLEN* */out IntPtr RowCount);
internal void Bind(OdbcStatementHandle hstmt, OdbcCommand command, short ordinal, CNativeBuffer parameterBuffer, bool allowReentrance) { ODBC32.RetCode retcode; ODBC32.SQL_C sql_c_type = _prepared_Sql_C_Type; ODBC32.SQL_PARAM sqldirection = SqlDirectionFromParameterDirection(); int offset = _preparedOffset; int size = _preparedSize; object value = _preparedValue; int cbValueSize = GetValueSize(value, offset); // count of bytes for the data int cchSize = GetColumnSize(value, offset, ordinal); // count of bytes for the data, used to allocate the buffer length byte precision = GetParameterPrecision(value); byte scale = GetParameterScale(value); int cbActual; HandleRef valueBuffer = parameterBuffer.PtrOffset(_preparedValueOffset, _preparedBufferSize); HandleRef intBuffer = parameterBuffer.PtrOffset(_preparedIntOffset, IntPtr.Size); // for the numeric datatype we need to do some special case handling ... // if (ODBC32.SQL_C.NUMERIC == sql_c_type) { // for input/output parameters we need to adjust the scale of the input value since the convert function in // sqlsrv32 takes this scale for the output parameter (possible bug in sqlsrv32?) // if ((ODBC32.SQL_PARAM.INPUT_OUTPUT == sqldirection) && (value is decimal)) { if (scale < _internalScale) { while (scale < _internalScale) { value = ((decimal)value) * 10; scale++; } } } SetInputValue(value, sql_c_type, cbValueSize, precision, 0, parameterBuffer); // for output parameters we need to write precision and scale to the buffer since the convert function in // sqlsrv32 expects these values there (possible bug in sqlsrv32?) // if (ODBC32.SQL_PARAM.INPUT != sqldirection) { parameterBuffer.WriteInt16(_preparedValueOffset, (short)(((ushort)scale << 8) | (ushort)precision)); } } else { SetInputValue(value, sql_c_type, cbValueSize, size, offset, parameterBuffer); } // Try to reuse existing bindings if // the binding is valid (means we already went through binding all parameters) // the parametercollection is bound already // the bindtype ParameterType did not change (forced upgrade) if (!_hasChanged && (_boundSqlCType == sql_c_type) && (_boundParameterType == _bindtype._sql_type) && (_boundSize == cchSize) && (_boundScale == scale) && (_boundBuffer == valueBuffer.Handle) && (_boundIntbuffer == intBuffer.Handle) ) { return; } //SQLBindParameter retcode = hstmt.BindParameter( ordinal, // Parameter Number (short)sqldirection, // InputOutputType sql_c_type, // ValueType _bindtype._sql_type, // ParameterType (IntPtr)cchSize, // ColumnSize (IntPtr)scale, // DecimalDigits valueBuffer, // ParameterValuePtr (IntPtr)_preparedBufferSize, intBuffer); // StrLen_or_IndPtr if (ODBC32.RetCode.SUCCESS != retcode) { if ("07006" == command.GetDiagSqlState()) { command.Connection.FlagRestrictedSqlBindType(_bindtype._sql_type); if (allowReentrance) { this.Bind(hstmt, command, ordinal, parameterBuffer, false); return; } } command.Connection.HandleError(hstmt, retcode); } _hasChanged = false; _boundSqlCType = sql_c_type; _boundParameterType = _bindtype._sql_type; _boundSize = cchSize; _boundScale = scale; _boundBuffer = valueBuffer.Handle; _boundIntbuffer = intBuffer.Handle; if (ODBC32.SQL_C.NUMERIC == sql_c_type) { OdbcDescriptorHandle hdesc = command.GetDescriptorHandle(ODBC32.SQL_ATTR.APP_PARAM_DESC); // descriptor handle is cached on command wrapper, don't release it // Set descriptor Type // //SQLSetDescField(hdesc, i+1, SQL_DESC_TYPE, (void *)SQL_C_NUMERIC, 0); retcode = hdesc.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.TYPE, (IntPtr)ODBC32.SQL_C.NUMERIC); if (ODBC32.RetCode.SUCCESS != retcode) { command.Connection.HandleError(hstmt, retcode); } // Set precision // cbActual = (int)precision; //SQLSetDescField(hdesc, i+1, SQL_DESC_PRECISION, (void *)precision, 0); retcode = hdesc.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.PRECISION, (IntPtr)cbActual); if (ODBC32.RetCode.SUCCESS != retcode) { command.Connection.HandleError(hstmt, retcode); } // Set scale // // SQLSetDescField(hdesc, i+1, SQL_DESC_SCALE, (void *)llen, 0); cbActual = (int)scale; retcode = hdesc.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.SCALE, (IntPtr)cbActual); if (ODBC32.RetCode.SUCCESS != retcode) { command.Connection.HandleError(hstmt, retcode); } // Set data pointer // // SQLSetDescField(hdesc, i+1, SQL_DESC_DATA_PTR, (void *)&numeric, 0); retcode = hdesc.SetDescriptionField2(ordinal, ODBC32.SQL_DESC.DATA_PTR, valueBuffer); if (ODBC32.RetCode.SUCCESS != retcode) { command.Connection.HandleError(hstmt, retcode); } } }
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLMoreResults( /*SQLHSTMT*/OdbcStatementHandle StatementHandle);
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLNumResultCols( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, /*SQLSMALLINT* */out Int16 ColumnCount);
private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, string method, bool needReader, object?[]?methodArguments, ODBC32.SQL_API odbcApiMethod) { // MDAC 68324 OdbcDataReader?localReader = null; try { DisposeDeadDataReader(); // this is a no-op if cmdState is not Fetching ValidateConnectionAndTransaction(method); // cmdState will change to Executing if (0 != (CommandBehavior.SingleRow & behavior)) { // CommandBehavior.SingleRow implies CommandBehavior.SingleResult behavior |= CommandBehavior.SingleResult; } ODBC32.RetCode retcode; OdbcStatementHandle stmt = GetStatementHandle().StatementHandle !; _cmdWrapper !.Canceling = false; if (null != _weakDataReaderReference) { if (_weakDataReaderReference.IsAlive) { object?target = _weakDataReaderReference.Target; if (null != target && _weakDataReaderReference.IsAlive) { if (!((OdbcDataReader)target).IsClosed) { throw ADP.OpenReaderExists(); // MDAC 66411 } } } } localReader = new OdbcDataReader(this, _cmdWrapper, behavior); //Set command properties //Not all drivers support timeout. So fail silently if error if (!Connection !.ProviderInfo.NoQueryTimeout) { TrySetStatementAttribute(stmt, ODBC32.SQL_ATTR.QUERY_TIMEOUT, (IntPtr)this.CommandTimeout); } // todo: If we remember the state we can omit a lot of SQLSetStmtAttrW calls ... // if we do not create a reader we do not even need to do that if (needReader) { if (Connection.IsV3Driver) { if (!Connection.ProviderInfo.NoSqlSoptSSNoBrowseTable && !Connection.ProviderInfo.NoSqlSoptSSHiddenColumns) { // Need to get the metadata information //SQLServer actually requires browse info turned on ahead of time... //Note: We ignore any failures, since this is SQLServer specific //We won't specialcase for SQL Server but at least for non-V3 drivers if (localReader.IsBehavior(CommandBehavior.KeyInfo)) { if (!_cmdWrapper._ssKeyInfoModeOn) { TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.NOBROWSETABLE, (IntPtr)ODBC32.SQL_NB.ON); TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.HIDDEN_COLUMNS, (IntPtr)ODBC32.SQL_HC.ON); _cmdWrapper._ssKeyInfoModeOff = false; _cmdWrapper._ssKeyInfoModeOn = true; } } else { if (!_cmdWrapper._ssKeyInfoModeOff) { TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.NOBROWSETABLE, (IntPtr)ODBC32.SQL_NB.OFF); TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.HIDDEN_COLUMNS, (IntPtr)ODBC32.SQL_HC.OFF); _cmdWrapper._ssKeyInfoModeOff = true; _cmdWrapper._ssKeyInfoModeOn = false; } } } } } if (localReader.IsBehavior(CommandBehavior.KeyInfo) || localReader.IsBehavior(CommandBehavior.SchemaOnly)) { retcode = stmt.Prepare(CommandText); if (ODBC32.RetCode.SUCCESS != retcode) { _connection !.HandleError(stmt, retcode); } } bool mustRelease = false; CNativeBuffer?parameterBuffer = _cmdWrapper._nativeParameterBuffer; try { //Handle Parameters //Note: We use the internal variable as to not instante a new object collection, //for the common case of using no parameters. if ((null != _parameterCollection) && (0 < _parameterCollection.Count)) { int parameterBufferSize = _parameterCollection.CalcParameterBufferSize(this); if (null == parameterBuffer || parameterBuffer.Length < parameterBufferSize) { if (null != parameterBuffer) { parameterBuffer.Dispose(); } parameterBuffer = new CNativeBuffer(parameterBufferSize); _cmdWrapper._nativeParameterBuffer = parameterBuffer; } else { parameterBuffer.ZeroMemory(); } parameterBuffer.DangerousAddRef(ref mustRelease); _parameterCollection.Bind(this, _cmdWrapper, parameterBuffer); } if (!localReader.IsBehavior(CommandBehavior.SchemaOnly)) { // Can't get the KeyInfo after command execution (SQL Server only since it does not support multiple // results on the same connection). Stored procedures (SP) do not return metadata before actual execution // Need to check the column count since the command type may not be set to SP for a SP. if ((localReader.IsBehavior(CommandBehavior.KeyInfo) || localReader.IsBehavior(CommandBehavior.SchemaOnly)) && (CommandType != CommandType.StoredProcedure)) { short cColsAffected; retcode = stmt.NumberOfResultColumns(out cColsAffected); if (retcode == ODBC32.RetCode.SUCCESS || retcode == ODBC32.RetCode.SUCCESS_WITH_INFO) { if (cColsAffected > 0) { localReader.GetSchemaTable(); } } else if (retcode == ODBC32.RetCode.NO_DATA) { // do nothing } else { // any other returncode indicates an error _connection !.HandleError(stmt, retcode); } } switch (odbcApiMethod) { case ODBC32.SQL_API.SQLEXECDIRECT: if (localReader.IsBehavior(CommandBehavior.KeyInfo) || _isPrepared) { //Already prepared, so use SQLExecute retcode = stmt.Execute(); // Build metadata here // localReader.GetSchemaTable(); } else { #if DEBUG //if (AdapterSwitches.OleDbTrace.TraceInfo) { // ADP.DebugWriteLine("SQLExecDirectW: " + CommandText); //} #endif //SQLExecDirect retcode = stmt.ExecuteDirect(CommandText); } break; case ODBC32.SQL_API.SQLTABLES: retcode = stmt.Tables((string)methodArguments ![0] !, //TableCatalog (string)methodArguments[1] !, //TableSchema, (string)methodArguments[2] !, //TableName (string)methodArguments[3] !); //TableType break;
static internal extern /*SQLRETURN*/ODBC32.RetCode SQLPrepareW( /*SQLHSTMT*/OdbcStatementHandle StatementHandle, [In, MarshalAs(UnmanagedType.LPWStr)] /*SQLCHAR* */string StatementText, /*SQLINTEGER*/Int32 TextLength);