Ejemplo n.º 1
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);
                }
            }
        }
Ejemplo n.º 2
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()) {
                    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);
                }
            }
        }
Ejemplo n.º 3
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);
                    }
                }
            }
        }
 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);
             }
         }
     }
 }
Ejemplo n.º 5
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);
            }
        }