internal ODBC32.RetCode ColumnAttribute(int columnNumber, short fieldIdentifier, CNativeBuffer characterAttribute, out short stringLength, out SQLLEN numericAttribute)
 {
     IntPtr ptr;
     ODBC32.RetCode retcode = UnsafeNativeMethods.SQLColAttributeW(this, (short) columnNumber, fieldIdentifier, characterAttribute, characterAttribute.ShortLength, out stringLength, out ptr);
     numericAttribute = new SQLLEN(ptr);
     ODBC.TraceODBC(3, "SQLColAttributeW", retcode);
     return retcode;
 }
 internal void Dispose()
 {
     if (this._dataReaderBuf != null)
     {
         this._dataReaderBuf.Dispose();
         this._dataReaderBuf = null;
     }
     this.DisposeStatementHandle();
     CNativeBuffer buffer = this._nativeParameterBuffer;
     this._nativeParameterBuffer = null;
     if (buffer != null)
     {
         buffer.Dispose();
     }
     this._ssKeyInfoModeOn = false;
     this._ssKeyInfoModeOff = false;
 }
        internal void SetInputValue(object value, ODBC32.SQL_C sql_c_type, int cbsize, int sizeorprecision, int offset, CNativeBuffer parameterBuffer) { //Handle any input params
            if((ParameterDirection.Input == _internalDirection) || (ParameterDirection.InputOutput == _internalDirection)) {
                //Note: (lang) "null" means to use the servers default (not DBNull).
                //We probably should just not have bound this parameter, period, but that
                //would mess up the users question marks, etc...
                if((null == value)) {
                    parameterBuffer.WriteIntPtr(_preparedIntOffset, (IntPtr)ODBC32.SQL_DEFAULT_PARAM);
                }
                else if(Convert.IsDBNull(value)) {
                    parameterBuffer.WriteIntPtr(_preparedIntOffset, (IntPtr)ODBC32.SQL_NULL_DATA);
                }
                else {
                    switch(sql_c_type) {
                    case ODBC32.SQL_C.CHAR:
                    case ODBC32.SQL_C.WCHAR:
                    case ODBC32.SQL_C.BINARY:
                        //StrLen_or_IndPtr is ignored except for Character or Binary or data.
                        parameterBuffer.WriteIntPtr(_preparedIntOffset, (IntPtr)cbsize);
                        break;
                    default:
                        parameterBuffer.WriteIntPtr(_preparedIntOffset, IntPtr.Zero);
                        break;

                    }

                    //Place the input param value into the native buffer
                    parameterBuffer.MarshalToNative(_preparedValueOffset, value, sql_c_type, sizeorprecision, offset);
                }
            }
            else {
                // always set ouput only and return value parameter values to null when executing
                _internalValue = null;

                //Always initialize the intbuffer (for output params).  Since we need to know
                //if/when the parameters are available for output. (ie: when is the buffer valid...)
                //if (_sqldirection != ODBC32.SQL_PARAM.INPUT)
                parameterBuffer.WriteIntPtr(_preparedIntOffset, (IntPtr)ODBC32.SQL_NULL_DATA);
            }
        }
        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);
                }
            }
        }
Example #5
0
        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;
Example #6
0
        internal ODBC32.RetCode ColumnAttribute(int columnNumber, short fieldIdentifier, CNativeBuffer characterAttribute, out short stringLength, out SQLLEN numericAttribute)
        {
            IntPtr result;

            ODBC32.RetCode retcode = Interop.Odbc.SQLColAttributeW(this, checked ((short)columnNumber), fieldIdentifier, characterAttribute, characterAttribute.ShortLength, out stringLength, out result);
            numericAttribute = new SQLLEN(result);
            ODBC.TraceODBC(3, "SQLColAttributeW", retcode);
            return(retcode);
        }
 internal ODBC32.RetCode GetData(int index, ODBC32.SQL_C sqlctype, CNativeBuffer buffer, int cb, out IntPtr cbActual) {
     ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetData(this,
                     checked((ushort)index),
                     sqlctype,
                     buffer,
                     new IntPtr(cb),
                     out cbActual);
     ODBC.TraceODBC(3, "SQLGetData", retcode);
     return retcode;
 }
        internal void SetInputValue(object value, ODBC32.SQL_C sql_c_type, int cbsize, int sizeorprecision, int offset, CNativeBuffer parameterBuffer)
        {
            if ((ParameterDirection.Input != this._internalDirection) && (ParameterDirection.InputOutput != this._internalDirection))
            {
                this._internalValue = null;
                parameterBuffer.WriteIntPtr(this._preparedIntOffset, (IntPtr) (-1));
            }
            else if (value == null)
            {
                parameterBuffer.WriteIntPtr(this._preparedIntOffset, (IntPtr) (-5));
            }
            else if (Convert.IsDBNull(value))
            {
                parameterBuffer.WriteIntPtr(this._preparedIntOffset, (IntPtr) (-1));
            }
            else
            {
                switch (sql_c_type)
                {
                    case ODBC32.SQL_C.WCHAR:
                    case ODBC32.SQL_C.BINARY:
                    case ODBC32.SQL_C.CHAR:
                        parameterBuffer.WriteIntPtr(this._preparedIntOffset, (IntPtr) cbsize);
                        break;

                    default:
                        parameterBuffer.WriteIntPtr(this._preparedIntOffset, IntPtr.Zero);
                        break;
                }
                parameterBuffer.MarshalToNative(this._preparedValueOffset, value, sql_c_type, sizeorprecision, offset);
            }
        }
 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);
             }
         }
     }
 }
Example #10
0
        internal void SetInputValue(object value, ODBC32.SQL_C sql_c_type, int cbsize, int sizeorprecision, int offset, CNativeBuffer parameterBuffer)
        {
            if ((ParameterDirection.Input != this._internalDirection) && (ParameterDirection.InputOutput != this._internalDirection))
            {
                this._internalValue = null;
                parameterBuffer.WriteIntPtr(this._preparedIntOffset, (IntPtr)(-1));
            }
            else if (value == null)
            {
                parameterBuffer.WriteIntPtr(this._preparedIntOffset, (IntPtr)(-5));
            }
            else if (Convert.IsDBNull(value))
            {
                parameterBuffer.WriteIntPtr(this._preparedIntOffset, (IntPtr)(-1));
            }
            else
            {
                switch (sql_c_type)
                {
                case ODBC32.SQL_C.WCHAR:
                case ODBC32.SQL_C.BINARY:
                case ODBC32.SQL_C.CHAR:
                    parameterBuffer.WriteIntPtr(this._preparedIntOffset, (IntPtr)cbsize);
                    break;

                default:
                    parameterBuffer.WriteIntPtr(this._preparedIntOffset, IntPtr.Zero);
                    break;
                }
                parameterBuffer.MarshalToNative(this._preparedValueOffset, value, sql_c_type, sizeorprecision, offset);
            }
        }
Example #11
0
        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)
        {
            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 static extern ODBC32.RetCode SQLGetDescFieldW(OdbcDescriptorHandle StatementHandle, short RecNumber, ODBC32.SQL_DESC FieldIdentifier, CNativeBuffer ValuePointer, int BufferLength, out int StringLength);
 internal static extern ODBC32.RetCode SQLGetData(OdbcStatementHandle StatementHandle, ushort ColumnNumber, ODBC32.SQL_C TargetType, CNativeBuffer TargetValue, IntPtr BufferLength, out IntPtr StrLen_or_Ind);
 internal static extern ODBC32.RetCode SQLColAttributeW(OdbcStatementHandle StatementHandle, short ColumnNumber, short FieldIdentifier, CNativeBuffer CharacterAttribute, short BufferLength, out short StringLength, out IntPtr NumericAttribute);
Example #16
0
        internal void Bind(HandleRef hstmt, OdbcCommand parent, short ordinal, CNativeBuffer buffer, CNativeBuffer intbuffer)
        {
            ODBC32.RETCODE retcode;
            int            cbActual;

            ODBC32.SQL_C sql_c_type;

            object value = GetParameterValue();

            switch (Direction)
            {
            case ParameterDirection.Input:
                Marshal.WriteInt32(intbuffer.Ptr, 0);
                break;

            case ParameterDirection.Output:
            case ParameterDirection.ReturnValue:
                Marshal.WriteInt32(intbuffer.Ptr, ODBC32.SQL_NULL_DATA);
                break;

            case ParameterDirection.InputOutput:
                Marshal.WriteInt32(intbuffer.Ptr, 0);
                break;

            default:
                throw ADP.InvalidParameterDirection((int)value, ParameterName);
            }

            // before we can do anything we need to verify if there is support
            // for certain data types
            //
            switch (_bindtype._sql_type)
            {
            case ODBC32.SQL_TYPE.DECIMAL:
            case ODBC32.SQL_TYPE.NUMERIC:
                Debug.Assert((null == value) || Convert.IsDBNull(value) || (value is Decimal), "value not decimal");
                if ((_parent.Connection.OdbcMajorVersion < 3) ||
                    !((OdbcParameterCollection)_parent).Connection.TestTypeSupport(ODBC32.SQL_TYPE.NUMERIC))
                {
                    // No support for NUMERIC
                    // Change the type
                    _bindtype = TypeMap._VarChar;
                    if ((null != value) && !Convert.IsDBNull(value))
                    {
                        value = ((Decimal)value).ToString();
                    }
                }
                break;

            case ODBC32.SQL_TYPE.BIGINT:
                Debug.Assert((null == value) || Convert.IsDBNull(value) || (value is Int64), "value not Int64");
                if (_parent.Connection.OdbcMajorVersion < 3)
                {
                    // No support for BIGINT
                    // Change the type
                    _bindtype = TypeMap._VarChar;
                    if ((null != value) && !Convert.IsDBNull(value))
                    {
                        value = ((Int64)value).ToString();
                    }
                }
                break;

            case ODBC32.SQL_TYPE.WCHAR:     // MDAC 68993
            case ODBC32.SQL_TYPE.WVARCHAR:
            case ODBC32.SQL_TYPE.WLONGVARCHAR:
                Debug.Assert((null == value) || Convert.IsDBNull(value) || (value is String), "value not string");
                if (!((OdbcParameterCollection)_parent).Connection.TestTypeSupport(_bindtype._sql_type))
                {
                    // No support for WCHAR, WVARCHAR or WLONGVARCHAR
                    // Change the type
                    if (ODBC32.SQL_TYPE.WCHAR == _bindtype._sql_type)
                    {
                        _bindtype = TypeMap._Char;
                    }
                    else if (ODBC32.SQL_TYPE.WVARCHAR == _bindtype._sql_type)
                    {
                        _bindtype = TypeMap._VarChar;
                    }
                    else if (ODBC32.SQL_TYPE.WLONGVARCHAR == _bindtype._sql_type)
                    {
                        _bindtype = TypeMap._Text;
                    }
                }
                break;
            } // end switch

            // WARNING: this is very UGLY code but an internal compilererror forces me to do so
            // (MDAC BUG 72163)
            //

            // Conversation from WCHAR to CHAR, VARCHAR or LONVARCHAR (AnsiString) is different for some providers
            // we need to chonvert WCHAR to CHAR and bind as sql_c_type = CHAR
            //
            sql_c_type = (_parent.Connection.OdbcMajorVersion >= 3) ? _bindtype._sql_c : _bindtype._param_sql_c;

            if ((_parent.Connection.OdbcMajorVersion < 3) && (_bindtype._param_sql_c == ODBC32.SQL_C.CHAR))
            {
                if ((value is String) && (null != value) && !Convert.IsDBNull(value))
                {
                    int         lcid    = System.Globalization.CultureInfo.CurrentCulture.LCID;
                    CultureInfo culInfo = new CultureInfo(lcid);
                    Encoding    cpe     = System.Text.Encoding.GetEncoding(culInfo.TextInfo.ANSICodePage);
                    value = cpe.GetBytes(value.ToString());
                }
            }

            int cbParameterSize = GetParameterSize(value);      // count of bytes for the data, for SQLBindParameter
            int cbValueSize     = GetValueSize(value);          // count of bytes for the data
            int cchSize         = GetColumnSize(value);         // count of bytes for the data, used to allocate the buffer length

            // here we upgrade the datatypes if the given values size is bigger than the types columnsize
            //

            switch (_bindtype._sql_type)
            {
            case ODBC32.SQL_TYPE.VARBINARY:     // MDAC 74372
                // Note: per definition DbType.Binary does not support more than 8000 bytes so we change the type for binding
                if ((cbParameterSize > 8000))
                {
                    _bindtype = TypeMap._Image;
                }                                       // will change to LONGVARBINARY
                break;

            case ODBC32.SQL_TYPE.VARCHAR:     // MDAC 74372
                // Note: per definition DbType.Binary does not support more than 8000 bytes so we change the type for binding
                if ((cbParameterSize > 8000))
                {
                    _bindtype = TypeMap._Text;
                }                                       // will change to LONGVARCHAR
                break;

            case ODBC32.SQL_TYPE.WVARCHAR:      // MDAC 75099
                // Note: per definition DbType.Binary does not support more than 8000 bytes so we change the type for binding
                if ((cbParameterSize > 4000))
                {
                    _bindtype = TypeMap._NText;
                }                                        // will change to WLONGVARCHAR
                break;
            } // end switch

            //Allocate a our buffer to hold the input/output data
            //Note: cbValueSize is used in the SetInputValue to indicate how many bytes of variable
            //length data (which doesn't include the null terminator as spec'd), however our raw
            //buffer needs extra room for this
            buffer.EnsureAlloc(cbParameterSize);

            byte precision = GetParameterPrecision(value);
            byte scale     = GetParameterScale(value);

            // 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 < this.scale)
                    {
                        while (scale < this.scale)
                        {
                            value = ((decimal)value) * 10;
                            scale++;
                        }
                    }
                }
                SetInputValue(cbValueSize, value, precision, buffer, intbuffer);

                // 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)
                {
                    Marshal.WriteByte(buffer.Ptr, 0, (byte)precision);
                    Marshal.WriteByte(buffer.Ptr, 1, (byte)scale);
                }
            }
            else
            {
                SetInputValue(cbValueSize, value, precision, buffer, intbuffer);
            }


            // Try to reuse existing bindings
            //

            if (_parent.BindingIsValid && _parent.CollectionIsBound)
            {
                return;
            }

            //SQLBindParameter
            retcode = (ODBC32.RETCODE)
                      UnsafeNativeMethods.Odbc32.SQLBindParameter(
                hstmt,                                          // StatementHandle
                ordinal,                                        // Parameter Number
                (short)this._sqldirection,                      // InputOutputType
                (short)sql_c_type,                              // ValueType
                (short)_bindtype._sql_type,                     // ParameterType
                (IntPtr)cchSize,                                // ColumnSize
                (IntPtr)scale,                                  // DecimalDigits
                buffer,                                         // ParameterValuePtr
                (IntPtr)buffer.Length,                          // BufferLength
                intbuffer.Ptr);                                 // StrLen_or_IndPtr

            if (ODBC32.RETCODE.SUCCESS != retcode)
            {
                ((OdbcParameterCollection)_parent).Connection.HandleError(hstmt, ODBC32.SQL_HANDLE.STMT, retcode);
            }

            if (ODBC32.SQL_C.NUMERIC == sql_c_type)
            {
                HandleRef hdesc = parent.GetDescriptorHandle();

                // Set descriptor Type
                //
                //SQLSetDescField(hdesc, i+1, SQL_DESC_TYPE, (void *)SQL_C_NUMERIC, 0);
                retcode = (ODBC32.RETCODE)
                          UnsafeNativeMethods.Odbc32.SQLSetDescFieldW(
                    hdesc,
                    ordinal,
                    (short)ODBC32.SQL_DESC.TYPE,
                    new HandleRef(null, (IntPtr)ODBC32.SQL_C.NUMERIC),
                    0);
                if (ODBC32.RETCODE.SUCCESS != retcode)
                {
                    ((OdbcParameterCollection)_parent).Connection.HandleError(hstmt, ODBC32.SQL_HANDLE.STMT, retcode);
                }


                // Set precision
                //
                cbActual = (int)precision;
                //SQLSetDescField(hdesc, i+1, SQL_DESC_PRECISION, (void *)precision, 0);
                retcode = (ODBC32.RETCODE)
                          UnsafeNativeMethods.Odbc32.SQLSetDescFieldW(
                    hdesc,
                    ordinal,
                    (short)ODBC32.SQL_DESC.PRECISION,
                    new HandleRef(this, (IntPtr)cbActual),
                    0);
                if (ODBC32.RETCODE.SUCCESS != retcode)
                {
                    ((OdbcParameterCollection)_parent).Connection.HandleError(hstmt, ODBC32.SQL_HANDLE.STMT, retcode);
                }


                // Set scale
                //
                // SQLSetDescField(hdesc, i+1, SQL_DESC_SCALE,  (void *)llen, 0);
                cbActual = (int)scale;
                retcode  = (ODBC32.RETCODE)
                           UnsafeNativeMethods.Odbc32.SQLSetDescFieldW(
                    hdesc, ordinal,
                    (short)ODBC32.SQL_DESC.SCALE,
                    new HandleRef(this, (IntPtr)cbActual),
                    0);
                if (ODBC32.RETCODE.SUCCESS != retcode)
                {
                    ((OdbcParameterCollection)_parent).Connection.HandleError(hstmt, ODBC32.SQL_HANDLE.STMT, retcode);
                }

                // Set data pointer
                //
                // SQLSetDescField(hdesc, i+1, SQL_DESC_DATA_PTR,  (void *)&numeric, 0);
                retcode = (ODBC32.RETCODE)
                          UnsafeNativeMethods.Odbc32.SQLSetDescFieldW(
                    hdesc, ordinal,
                    (short)ODBC32.SQL_DESC.DATA_PTR,
                    buffer,
                    0);
                if (ODBC32.RETCODE.SUCCESS != retcode)
                {
                    ((OdbcParameterCollection)_parent).Connection.HandleError(hstmt, ODBC32.SQL_HANDLE.STMT, retcode);
                }
                // Don't free handle descriptors. They are not allocated.
                // retcode =  (ODBC32.RETCODE) UnsafeNativeMethods.Odbc32.SQLFreeHandle( (short)ODBC32.SQL_HANDLE.DESC, hdesc);
            }
        }
 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);
        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 GetOutputValue(CNativeBuffer parameterBuffer)
 {
     if (!this._hasChanged && ((this._bindtype != null) && (this._internalDirection != ParameterDirection.Input)))
     {
         TypeMap map = this._bindtype;
         this._bindtype = null;
         int cb = (int) parameterBuffer.ReadIntPtr(this._preparedIntOffset);
         if (-1 == cb)
         {
             this.Value = DBNull.Value;
         }
         else if ((0 <= cb) || (cb == -3))
         {
             this.Value = parameterBuffer.MarshalToManaged(this._preparedValueOffset, this._boundSqlCType, cb);
             if (((this._boundSqlCType == ODBC32.SQL_C.CHAR) && (this.Value != null)) && !Convert.IsDBNull(this.Value))
             {
                 CultureInfo info = new CultureInfo(CultureInfo.CurrentCulture.LCID);
                 this.Value = Encoding.GetEncoding(info.TextInfo.ANSICodePage).GetString((byte[]) this.Value);
             }
             if (((map != this._typemap) && (this.Value != null)) && (!Convert.IsDBNull(this.Value) && (this.Value.GetType() != this._typemap._type)))
             {
                 this.Value = decimal.Parse((string) this.Value, CultureInfo.CurrentCulture);
             }
         }
     }
 }
        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 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)) {
                            Int16 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
                                    (Int16)methodArguments[3],   //IndexTrpe
                                    (Int16)methodArguments[4]);  //Accuracy
                                break;

                            case ODBC32.SQL_API.SQLGETTYPEINFO:
                                retcode = stmt.GetTypeInfo((Int16)methodArguments[0]);  //SQL Type
                                break;

                            default:
                                // this should NEVER happen
                                Debug.Assert(false, "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();
                    }
                }

                this.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 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 Dispose() {
            if (null != _dataReaderBuf) {
                _dataReaderBuf.Dispose();
                _dataReaderBuf = null;
            }
            DisposeStatementHandle();

            CNativeBuffer buffer = _nativeParameterBuffer;
            _nativeParameterBuffer = null;
            if (null != buffer) {
                buffer.Dispose();
            }
            _ssKeyInfoModeOn = false;
            _ssKeyInfoModeOff = false;
        }
 internal ODBC32.RetCode GetDescriptionField(int i, ODBC32.SQL_DESC attribute, CNativeBuffer buffer, out int numericAttribute) {
     ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetDescFieldW(this, checked((short)i), attribute, buffer, buffer.ShortLength, out numericAttribute);
     ODBC.TraceODBC(3, "SQLGetDescFieldW", retcode);
     return retcode;
 }
Example #23
0
 internal ODBC32.RetCode GetDescriptionField(int i, ODBC32.SQL_DESC attribute, CNativeBuffer buffer, out int numericAttribute)
 {
     ODBC32.RetCode retcode = Interop.Odbc.SQLGetDescFieldW(this, checked ((short)i), attribute, buffer, buffer.ShortLength, out numericAttribute);
     ODBC.TraceODBC(3, "SQLGetDescFieldW", retcode);
     return(retcode);
 }
Example #24
0
        internal void SetInputValue(object value, ODBC32.SQL_C sql_c_type, int cbsize, int sizeorprecision, int offset, CNativeBuffer parameterBuffer)
        { //Handle any input params
            if ((ParameterDirection.Input == _internalDirection) || (ParameterDirection.InputOutput == _internalDirection))
            {
                //Note: (lang) "null" means to use the servers default (not DBNull).
                //We probably should just not have bound this parameter, period, but that
                //would mess up the users question marks, etc...
                if ((null == value))
                {
                    parameterBuffer.WriteIntPtr(_preparedIntOffset, (IntPtr)ODBC32.SQL_DEFAULT_PARAM);
                }
                else if (Convert.IsDBNull(value))
                {
                    parameterBuffer.WriteIntPtr(_preparedIntOffset, (IntPtr)ODBC32.SQL_NULL_DATA);
                }
                else
                {
                    switch (sql_c_type)
                    {
                    case ODBC32.SQL_C.CHAR:
                    case ODBC32.SQL_C.WCHAR:
                    case ODBC32.SQL_C.BINARY:
                        //StrLen_or_IndPtr is ignored except for Character or Binary or data.
                        parameterBuffer.WriteIntPtr(_preparedIntOffset, (IntPtr)cbsize);
                        break;

                    default:
                        parameterBuffer.WriteIntPtr(_preparedIntOffset, IntPtr.Zero);
                        break;
                    }

                    //Place the input param value into the native buffer
                    parameterBuffer.MarshalToNative(_preparedValueOffset, value, sql_c_type, sizeorprecision, offset);
                }
            }
            else
            {
                // always set ouput only and return value parameter values to null when executing
                _internalValue = null;

                //Always initialize the intbuffer (for output params).  Since we need to know
                //if/when the parameters are available for output. (ie: when is the buffer valid...)
                //if (_sqldirection != ODBC32.SQL_PARAM.INPUT)
                parameterBuffer.WriteIntPtr(_preparedIntOffset, (IntPtr)ODBC32.SQL_NULL_DATA);
            }
        }
Example #25
0
        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 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))
                        {
                            Int16 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
                                                      (Int16)methodArguments[3],  //IndexTrpe
                                                      (Int16)methodArguments[4]); //Accuracy
                            break;

                        case ODBC32.SQL_API.SQLGETTYPEINFO:
                            retcode = stmt.GetTypeInfo((Int16)methodArguments[0]);      //SQL Type
                            break;

                        default:
                            // this should NEVER happen
                            Debug.Assert(false, "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();
                    }
                }

                this.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 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);
        }
Example #26
0
        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);
                }
            }
        }
 internal ODBC32.RetCode GetDescriptionField(int i, ODBC32.SQL_DESC attribute, CNativeBuffer buffer, out int numericAttribute)
 {
     ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetDescFieldW(this, (short)i, attribute, buffer, buffer.ShortLength, out numericAttribute);
     ODBC.TraceODBC(3, "SQLGetDescFieldW", retcode);
     return(retcode);
 }
 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);
        internal void GetOutputValue(CNativeBuffer parameterBuffer) { //Handle any output params

            // No value is available if the user fiddles with the parameters properties
            //
            if (_hasChanged) return;

            if ((null != _bindtype) && (_internalDirection != ParameterDirection.Input)) {

               TypeMap typemap = _bindtype;
                _bindtype = null;

                int cbActual = (int)parameterBuffer.ReadIntPtr(_preparedIntOffset);
                if (ODBC32.SQL_NULL_DATA == cbActual) {
                    Value = DBNull.Value;
                }
                else if ((0 <= cbActual)  || (cbActual == ODBC32.SQL_NTS)){ // safeguard
                    Value = parameterBuffer.MarshalToManaged(_preparedValueOffset, _boundSqlCType, cbActual);

                if (_boundSqlCType== ODBC32.SQL_C.CHAR) {
                    if ((null != Value) && !Convert.IsDBNull(Value)) {
                        int lcid = System.Globalization.CultureInfo.CurrentCulture.LCID;
                        CultureInfo culInfo = new CultureInfo(lcid);
                        Encoding cpe = System.Text.Encoding.GetEncoding(culInfo.TextInfo.ANSICodePage);
                        Value = cpe.GetString((Byte[])Value);
                    }
                }

                    if ((typemap != _typemap) && (null != Value) && !Convert.IsDBNull(Value) && (Value.GetType() != _typemap._type)) {
                        Debug.Assert(ODBC32.SQL_C.NUMERIC == _typemap._sql_c, "unexpected");
                        Value = Decimal.Parse((string)Value, System.Globalization.CultureInfo.CurrentCulture);
                    }
                }
            }
        }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLGetDescFieldW (
     /*SQLHSTMT*/OdbcDescriptorHandle StatementHandle,
     /*SQLUSMALLINT*/Int16 RecNumber,
     /*SQLUSMALLINT*/ODBC32.SQL_DESC FieldIdentifier,
     /*SQLPOINTER*/CNativeBuffer ValuePointer,
     /*SQLINTEGER*/Int32 BufferLength,
     /*SQLINTEGER* */out Int32 StringLength);
 internal void Bind(OdbcCommand command, CMDWrapper cmdWrapper, CNativeBuffer parameterBuffer)
 {
     for (int i = 0; i < this.Count; i++)
     {
         this[i].Bind(cmdWrapper.StatementHandle, command, (short) (i + 1), parameterBuffer, true);
     }
     this._rebindCollection = false;
 }
Example #32
0
        internal void SetInputValue(int size, object value, byte precision, CNativeBuffer buffer, CNativeBuffer intbuffer)   //Handle any input params
        {
#if DEBUG
            if (AdapterSwitches.DataValue.TraceVerbose)
            {
                Debug.WriteLine("SQLBindParameter:" + _typemap._odbcType.ToString("G") + " " + _bindtype._odbcType.ToString("G") + "(" + size + ")=" + ADP.ValueToString(value));
            }
#endif
            if ((ODBC32.SQL_PARAM.INPUT == _sqldirection) || (ODBC32.SQL_PARAM.INPUT_OUTPUT == _sqldirection))
            {
                ODBC32.SQL_C sql_c_type;
                sql_c_type = (_parent.Connection.OdbcMajorVersion >= 3) ? _bindtype._sql_c : _bindtype._param_sql_c;

                //Note: (lang) "null" means to use the servers default (not DBNull).
                //We probably should just not have bound this parameter, period, but that
                //would mess up the users question marks, etc...
                if ((null == value))
                {
                    Marshal.WriteInt32(intbuffer.Ptr, ODBC32.SQL_DEFAULT_PARAM);
                }
                else if (Convert.IsDBNull(value))
                {
                    Marshal.WriteInt32(intbuffer.Ptr, ODBC32.SQL_NULL_DATA);
                }
                else
                {
                    // Clear previous NULL_DATA status
                    Marshal.WriteInt32(intbuffer.Ptr, 0);
                    switch (sql_c_type)
                    {
                    case ODBC32.SQL_C.CHAR:
                    case ODBC32.SQL_C.WCHAR:
                    case ODBC32.SQL_C.BINARY:
                        //StrLen_or_IndPtr is ignored except for Character or Binary or data.
                        Marshal.WriteInt32(intbuffer.Ptr, size);
                        break;
                    }

                    //Place the input param value into the native buffer
                    buffer.MarshalToNative(value, sql_c_type, precision);
                }
            }
            else
            {
                // always set ouput only and return value parameter values to null when executing
                Value = null;

                //Always initialize the intbuffer (for output params).  Since we need to know
                //if/when the parameters are available for output. (ie: when is the buffer valid...)
                //if (_sqldirection != ODBC32.SQL_PARAM.INPUT)
                Marshal.WriteInt32(intbuffer.Ptr, ODBC32.SQL_NULL_DATA);
            }
        }