static internal extern /*SQLRETURN*/ODBC32.RetCode SQLBindCol(
     /*SQLHSTMT*/OdbcStatementHandle StatementHandle,
     /*SQLUSMALLINT*/UInt16 ColumnNumber,
     /*SQLSMALLINT*/ODBC32.SQL_C TargetType,
     /*SQLPOINTER*/IntPtr TargetValue,
     /*SQLLEN*/IntPtr BufferLength,
     /*SQLLEN* */IntPtr StrLen_or_Ind);
        internal OdbcHandle(OdbcStatementHandle parentHandle, ODBC32.SQL_ATTR attribute) : base(IntPtr.Zero, true)
        {
            ODBC32.RetCode code;
            this._handleType = ODBC32.SQL_HANDLE.DESC;
            bool success = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                int num;
                parentHandle.DangerousAddRef(ref success);
                code = parentHandle.GetStatementAttribute(attribute, out this.handle, out num);
            }
            finally
            {
                if (success)
                {
                    if (IntPtr.Zero != base.handle)
                    {
                        this._parentHandle = parentHandle;
                    }
                    else
                    {
                        parentHandle.DangerousRelease();
                    }
                }
            }
            if (ADP.PtrZero == base.handle)
            {
                throw ODBC.FailedToGetDescriptorHandle(code);
            }
        }
Exemple #3
0
        internal void FreeStatementHandle(ODBC32.STMT stmt)
        {
            DisposeDescriptorHandle();

            OdbcStatementHandle handle = _stmt;

            if (null != handle)
            {
                try
                {
                    ODBC32.RetCode retcode;
                    retcode = handle.FreeStatement(stmt);
                    StatementErrorHandler(retcode);
                }
                catch (Exception e)
                {
                    //
                    if (ADP.IsCatchableExceptionType(e))
                    {
                        _stmt = null;
                        handle.Dispose();
                    }

                    throw;
                }
            }
        }
Exemple #4
0
        // OdbcCommand.Cancel()
        //
        // In ODBC3.0 ... a call to SQLCancel when no processing is done has no effect at all
        // (ODBC Programmer's Reference ...)
        //

        public override void Cancel()
        {
            CMDWrapper wrapper = _cmdWrapper;

            if (null != wrapper)
            {
                wrapper.Canceling = true;
                OdbcStatementHandle stmt = wrapper.StatementHandle;
                if (null != stmt)
                {
                    lock (stmt)
                    {
                        // Cancel the statement
                        ODBC32.RetCode retcode = stmt.Cancel();

                        // copy of StatementErrorHandler, because stmt may become null
                        switch (retcode)
                        {
                        case ODBC32.RetCode.SUCCESS:
                        case ODBC32.RetCode.SUCCESS_WITH_INFO:
                            // don't fire info message events on cancel
                            break;

                        default:
                            throw wrapper.Connection.HandleErrorNoThrow(stmt, retcode);
                        }
                    }
                }
            }
        }
Exemple #5
0
        // Prepare
        //
        // if the CommandType property is set to TableDirect Prepare does nothing.
        // if the CommandType property is set to StoredProcedure Prepare should succeed but result
        // in a no-op
        //
        // throw InvalidOperationException
        // if the connection is not set
        // if the connection is not open
        //
        public override void Prepare()
        {
            ODBC32.RetCode retcode;

            ValidateOpenConnection(ADP.Prepare);

            if (0 != (ConnectionState.Fetching & _connection.InternalState))
            {
                throw ADP.OpenReaderExists();
            }

            if (CommandType == CommandType.TableDirect)
            {
                return; // do nothing
            }

            DisposeDeadDataReader();
            GetStatementHandle();

            OdbcStatementHandle stmt = _cmdWrapper.StatementHandle;

            retcode = stmt.Prepare(CommandText);


            if (ODBC32.RetCode.SUCCESS != retcode)
            {
                _connection.HandleError(stmt, retcode);
            }
            _isPrepared = true;
        }
 internal OdbcHandle(OdbcStatementHandle parentHandle, ODBC32.SQL_ATTR attribute) : base(IntPtr.Zero, true)
 {
     ODBC32.RetCode code;
     this._handleType = ODBC32.SQL_HANDLE.DESC;
     bool success = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         int num;
         parentHandle.DangerousAddRef(ref success);
         code = parentHandle.GetStatementAttribute(attribute, out this.handle, out num);
     }
     finally
     {
         if (success)
         {
             if (IntPtr.Zero != base.handle)
             {
                 this._parentHandle = parentHandle;
             }
             else
             {
                 parentHandle.DangerousRelease();
             }
         }
     }
     if (ADP.PtrZero == base.handle)
     {
         throw ODBC.FailedToGetDescriptorHandle(code);
     }
 }
        private static OdbcParameter[] DeriveParametersFromStoredProcedure(OdbcConnection connection, OdbcCommand command)
        {
            List <OdbcParameter> list            = new List <OdbcParameter>();
            CMDWrapper           statementHandle = command.GetStatementHandle();
            OdbcStatementHandle  hrHandle        = statementHandle.StatementHandle;
            string leftQuote = connection.QuoteChar("DeriveParameters");

            string[] strArray = MultipartIdentifier.ParseMultipartIdentifier(command.CommandText, leftQuote, leftQuote, '.', 4, true, "ODBC_ODBCCommandText", false);
            if (strArray[3] == null)
            {
                strArray[3] = command.CommandText;
            }
            ODBC32.RetCode retcode = hrHandle.ProcedureColumns(strArray[1], strArray[2], strArray[3], null);
            if (retcode != ODBC32.RetCode.SUCCESS)
            {
                connection.HandleError(hrHandle, retcode);
            }
            using (OdbcDataReader reader = new OdbcDataReader(command, statementHandle, CommandBehavior.Default))
            {
                reader.FirstResult();
                int fieldCount = reader.FieldCount;
                while (reader.Read())
                {
                    OdbcParameter item = new OdbcParameter {
                        ParameterName = reader.GetString(3)
                    };
                    switch (reader.GetInt16(4))
                    {
                    case 1:
                        item.Direction = ParameterDirection.Input;
                        break;

                    case 2:
                        item.Direction = ParameterDirection.InputOutput;
                        break;

                    case 4:
                        item.Direction = ParameterDirection.Output;
                        break;

                    case 5:
                        item.Direction = ParameterDirection.ReturnValue;
                        break;
                    }
                    item.OdbcType = TypeMap.FromSqlType((ODBC32.SQL_TYPE)reader.GetInt16(5))._odbcType;
                    item.Size     = reader.GetInt32(7);
                    switch (item.OdbcType)
                    {
                    case OdbcType.Decimal:
                    case OdbcType.Numeric:
                        item.ScaleInternal     = (byte)reader.GetInt16(9);
                        item.PrecisionInternal = (byte)reader.GetInt16(10);
                        break;
                    }
                    list.Add(item);
                }
            }
            retcode = hrHandle.CloseCursor();
            return(list.ToArray());
        }
 internal void DisposeKeyInfoStatementHandle()
 {
     OdbcStatementHandle handle = this._keyinfostmt;
     if (handle != null)
     {
         this._keyinfostmt = null;
         handle.Dispose();
     }
 }
Exemple #9
0
        internal void DisposeKeyInfoStatementHandle()
        {
            OdbcStatementHandle handle = this._keyinfostmt;

            if (handle != null)
            {
                this._keyinfostmt = null;
                handle.Dispose();
            }
        }
Exemple #10
0
        internal void DisposeKeyInfoStatementHandle()
        {
            OdbcStatementHandle handle = _keyinfostmt;

            if (null != handle)
            {
                _keyinfostmt = null;
                handle.Dispose();
            }
        }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLBindParameter(
     /*SQLHSTMT*/OdbcStatementHandle StatementHandle,
     /*SQLUSMALLINT*/UInt16 ParameterNumber,
     /*SQLSMALLINT*/Int16 ParamDirection,
     /*SQLSMALLINT*/ODBC32.SQL_C SQLCType,
     /*SQLSMALLINT*/Int16 SQLType,
     /*SQLULEN*/IntPtr    cbColDef,
     /*SQLSMALLINT*/IntPtr ibScale,
     /*SQLPOINTER*/HandleRef rgbValue,
     /*SQLLEN*/IntPtr BufferLength,
     /*SQLLEN* */HandleRef StrLen_or_Ind);
 internal void DisposeStatementHandle()
 {
     this.DisposeKeyInfoStatementHandle();
     this.DisposeDescriptorHandle();
     OdbcStatementHandle handle = this._stmt;
     if (handle != null)
     {
         this._stmt = null;
         handle.Dispose();
     }
 }
Exemple #13
0
        internal void DisposeStatementHandle()
        {
            this.DisposeKeyInfoStatementHandle();
            this.DisposeDescriptorHandle();
            OdbcStatementHandle handle = this._stmt;

            if (handle != null)
            {
                this._stmt = null;
                handle.Dispose();
            }
        }
Exemple #14
0
        internal void DisposeStatementHandle()
        {
            DisposeKeyInfoStatementHandle();
            DisposeDescriptorHandle();

            OdbcStatementHandle handle = _stmt;

            if (null != handle)
            {
                _stmt = null;
                handle.Dispose();
            }
        }
 private void TrySetStatementAttribute(OdbcStatementHandle stmt, ODBC32.SQL_ATTR stmtAttribute, IntPtr value)
 {
     if (stmt.SetStatementAttribute(stmtAttribute, value, ODBC32.SQL_IS.UINTEGER) == ODBC32.RetCode.ERROR)
     {
         string str;
         stmt.GetDiagnosticField(out str);
         switch (str)
         {
         case "HYC00":
         case "HY092":
             this.Connection.FlagUnsupportedStmtAttr(stmtAttribute);
             break;
         }
     }
 }
Exemple #16
0
        internal OdbcHandle(OdbcStatementHandle parentHandle, ODBC32.SQL_ATTR attribute) : base(IntPtr.Zero, true)
        {
            Debug.Assert((ODBC32.SQL_ATTR.APP_PARAM_DESC == attribute) || (ODBC32.SQL_ATTR.APP_ROW_DESC == attribute), "invalid attribute");
            _handleType = ODBC32.SQL_HANDLE.DESC;

            int cbActual;

            ODBC32.RetCode retcode;
            bool           mustRelease = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                // must addref before calling native so it won't be released just after
                parentHandle.DangerousAddRef(ref mustRelease);

                retcode = parentHandle.GetStatementAttribute(attribute, out base.handle, out cbActual);
            }
            finally
            {
                if (mustRelease)
                {
                    if (IntPtr.Zero != base.handle)
                    {
                        // must call DangerousAddRef after a handle is actually created
                        // since ReleaseHandle will only call DangerousRelease if a handle exists
                        _parentHandle = parentHandle;
                    }
                    else
                    {
                        // without a handle, ReleaseHandle may not be called
                        parentHandle.DangerousRelease();
                    }
                }
            }
            if (ADP.PtrZero == base.handle)
            {
                throw ODBC.FailedToGetDescriptorHandle(retcode);
            }
            // no info-message handle on getting a descriptor handle
        }
 public override void Prepare()
 {
     OdbcConnection.ExecutePermission.Demand();
     this.ValidateOpenConnection("Prepare");
     if ((ConnectionState.Fetching & this._connection.InternalState) != ConnectionState.Closed)
     {
         throw ADP.OpenReaderExists();
     }
     if (this.CommandType != System.Data.CommandType.TableDirect)
     {
         this.DisposeDeadDataReader();
         this.GetStatementHandle();
         OdbcStatementHandle statementHandle = this._cmdWrapper.StatementHandle;
         ODBC32.RetCode      retcode         = statementHandle.Prepare(this.CommandText);
         if (retcode != ODBC32.RetCode.SUCCESS)
         {
             this._connection.HandleError(statementHandle, retcode);
         }
         this._isPrepared = true;
     }
 }
Exemple #18
0
        internal void FreeKeyInfoStatementHandle(ODBC32.STMT stmt)
        {
            OdbcStatementHandle handle = this._keyinfostmt;

            if (handle != null)
            {
                try
                {
                    handle.FreeStatement(stmt);
                }
                catch (Exception exception)
                {
                    if (ADP.IsCatchableExceptionType(exception))
                    {
                        this._keyinfostmt = null;
                        handle.Dispose();
                    }
                    throw;
                }
            }
        }
Exemple #19
0
        internal void FreeKeyInfoStatementHandle(ODBC32.STMT stmt)
        {
            OdbcStatementHandle handle = _keyinfostmt;

            if (null != handle)
            {
                try {
                    handle.FreeStatement(stmt);
                }
                catch (Exception e) {
                    //
                    if (ADP.IsCatchableExceptionType(e))
                    {
                        _keyinfostmt = null;
                        handle.Dispose();
                    }

                    throw;
                }
            }
        }
Exemple #20
0
        private void TrySetStatementAttribute(OdbcStatementHandle stmt, ODBC32.SQL_ATTR stmtAttribute, IntPtr value)
        {
            ODBC32.RetCode retcode = stmt.SetStatementAttribute(
                stmtAttribute,
                value,
                ODBC32.SQL_IS.UINTEGER);

            if (retcode == ODBC32.RetCode.ERROR)
            {
                string sqlState;
                stmt.GetDiagnosticField(out sqlState);

                if ((sqlState == "HYC00") || (sqlState == "HY092"))
                {
                    Connection.FlagUnsupportedStmtAttr(stmtAttribute);
                }
                else
                {
                    // now what? Should we throw?
                }
            }
        }
Exemple #21
0
        internal void FreeStatementHandle(ODBC32.STMT stmt)
        {
            this.DisposeDescriptorHandle();
            OdbcStatementHandle handle = this._stmt;

            if (handle != null)
            {
                try
                {
                    ODBC32.RetCode retcode = handle.FreeStatement(stmt);
                    this.StatementErrorHandler(retcode);
                }
                catch (Exception exception)
                {
                    if (ADP.IsCatchableExceptionType(exception))
                    {
                        this._stmt = null;
                        handle.Dispose();
                    }
                    throw;
                }
            }
        }
        public override void Cancel()
        {
            CMDWrapper wrapper = this._cmdWrapper;

            if (wrapper != null)
            {
                wrapper.Canceling = true;
                OdbcStatementHandle statementHandle = wrapper.StatementHandle;
                if (statementHandle != null)
                {
                    lock (statementHandle)
                    {
                        ODBC32.RetCode retcode = statementHandle.Cancel();
                        switch (retcode)
                        {
                        case ODBC32.RetCode.SUCCESS:
                        case ODBC32.RetCode.SUCCESS_WITH_INFO:
                            return;
                        }
                        throw wrapper.Connection.HandleErrorNoThrow(statementHandle, retcode);
                    }
                }
            }
        }
 internal void CreateStatementHandle() {
     DisposeStatementHandle();
     _stmt =  _connection.CreateStatementHandle();
 }
        internal void DisposeStatementHandle() {
            DisposeKeyInfoStatementHandle();
            DisposeDescriptorHandle();

            OdbcStatementHandle handle = _stmt;
            if (null != handle) {
                _stmt = null;
                handle.Dispose();
            }
        }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLTablesW (
     /*SQLHSTMT*/OdbcStatementHandle StatementHandle,
     [In, MarshalAs(UnmanagedType.LPWStr)]
     /*SQLCHAR* */string CatalogName,
     /*SQLSMALLINT*/Int16 NameLen1,
     [In, MarshalAs(UnmanagedType.LPWStr)]
     /*SQLCHAR* */string SchemaName,
     /*SQLSMALLINT*/Int16 NameLen2,
     [In, MarshalAs(UnmanagedType.LPWStr)]
     /*SQLCHAR* */string TableName,
     /*SQLSMALLINT*/Int16 NameLen3,
     [In, MarshalAs(UnmanagedType.LPWStr)]
     /*SQLCHAR* */string TableType,
     /*SQLSMALLINT*/Int16 NameLen4);
 internal OdbcDescriptorHandle(OdbcStatementHandle statementHandle, ODBC32.SQL_ATTR attribute) : base(statementHandle, attribute) {
 }
Exemple #27
0
 internal void CreateKeyInfoStatementHandle()
 {
     DisposeKeyInfoStatementHandle();
     _keyinfostmt = _connection.CreateStatementHandle();
 }
 internal void CreateKeyInfoStatementHandle() {
     DisposeKeyInfoStatementHandle();
     _keyinfostmt =  _connection.CreateStatementHandle();
 }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLColAttributeW (
     /*SQLHSTMT*/OdbcStatementHandle StatementHandle,
     /*SQLUSMALLINT*/Int16 ColumnNumber,
     /*SQLUSMALLINT*/Int16 FieldIdentifier,
     /*SQLPOINTER*/CNativeBuffer CharacterAttribute,
     /*SQLSMALLINT*/Int16 BufferLength,
     /*SQLSMALLINT* */out Int16 StringLength,
     /*SQLPOINTER*/out IntPtr NumericAttribute);
 internal void DisposeKeyInfoStatementHandle() {
     OdbcStatementHandle handle = _keyinfostmt;
     if (null != handle) {
         _keyinfostmt = null;
         handle.Dispose();
     }
 }
        // DeriveParametersFromStoredProcedure (
        //  OdbcConnection connection,
        //  OdbcCommand command);
        //
        // Uses SQLProcedureColumns to create an array of OdbcParameters
        //

        static private OdbcParameter[] DeriveParametersFromStoredProcedure(OdbcConnection connection, OdbcCommand command)
        {
            List <OdbcParameter> rParams = new List <OdbcParameter>();

            // following call ensures that the command has a statement handle allocated
            CMDWrapper          cmdWrapper = command.GetStatementHandle();
            OdbcStatementHandle hstmt      = cmdWrapper.StatementHandle;
            int cColsAffected;

            // maps an enforced 4-part qualified string as follows
            // parts[0] = null  - ignored but removal would be a run-time breaking change from V1.0
            // parts[1] = CatalogName (optional, may be null)
            // parts[2] = SchemaName (optional, may be null)
            // parts[3] = ProcedureName
            //
            string quote = connection.QuoteChar(ADP.DeriveParameters);

            string[] parts = MultipartIdentifier.ParseMultipartIdentifier(command.CommandText, quote, quote, '.', 4, true, Res.ODBC_ODBCCommandText, false);
            if (null == parts[3])
            { // match Everett behavior, if the commandtext is nothing but whitespace set the command text to the whitespace
                parts[3] = command.CommandText;
            }
            // note: native odbc appears to ignore all but the procedure name
            ODBC32.RetCode retcode = hstmt.ProcedureColumns(parts[1], parts[2], parts[3], null);

            // Note: the driver does not return an error if the given stored procedure does not exist
            // therefore we cannot handle that case and just return not parameters.

            if (ODBC32.RetCode.SUCCESS != retcode)
            {
                connection.HandleError(hstmt, retcode);
            }

            using (OdbcDataReader reader = new OdbcDataReader(command, cmdWrapper, CommandBehavior.Default))
            {
                reader.FirstResult();
                cColsAffected = reader.FieldCount;

                // go through the returned rows and filter out relevant parameter data
                //
                while (reader.Read())
                {
                    // devnote: column types are specified in the ODBC Programmer's Reference
                    // COLUMN_TYPE      Smallint    16bit
                    // COLUMN_SIZE      Integer     32bit
                    // DECIMAL_DIGITS   Smallint    16bit
                    // NUM_PREC_RADIX   Smallint    16bit

                    OdbcParameter parameter = new OdbcParameter();

                    parameter.ParameterName = reader.GetString(ODBC32.COLUMN_NAME - 1);
                    switch ((ODBC32.SQL_PARAM)reader.GetInt16(ODBC32.COLUMN_TYPE - 1))
                    {
                    case ODBC32.SQL_PARAM.INPUT:
                        parameter.Direction = ParameterDirection.Input;
                        break;

                    case ODBC32.SQL_PARAM.OUTPUT:
                        parameter.Direction = ParameterDirection.Output;
                        break;

                    case ODBC32.SQL_PARAM.INPUT_OUTPUT:
                        parameter.Direction = ParameterDirection.InputOutput;
                        break;

                    case ODBC32.SQL_PARAM.RETURN_VALUE:
                        parameter.Direction = ParameterDirection.ReturnValue;
                        break;

                    default:
                        Debug.Assert(false, "Unexpected Parametertype while DeriveParamters");
                        break;
                    }
                    parameter.OdbcType = TypeMap.FromSqlType((ODBC32.SQL_TYPE)reader.GetInt16(ODBC32.DATA_TYPE - 1))._odbcType;
                    parameter.Size     = (int)reader.GetInt32(ODBC32.COLUMN_SIZE - 1);
                    switch (parameter.OdbcType)
                    {
                    case OdbcType.Decimal:
                    case OdbcType.Numeric:
                        parameter.ScaleInternal     = (Byte)reader.GetInt16(ODBC32.DECIMAL_DIGITS - 1);
                        parameter.PrecisionInternal = (Byte)reader.GetInt16(ODBC32.NUM_PREC_RADIX - 1);
                        break;
                    }
                    rParams.Add(parameter);
                }
            }
            retcode = hstmt.CloseCursor();
            return(rParams.ToArray());;
        }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLGetData(
     /*SQLHSTMT*/OdbcStatementHandle StatementHandle,
     /*SQLUSMALLINT*/UInt16 ColumnNumber,
     /*SQLSMALLINT*/ODBC32.SQL_C TargetType,
     /*SQLPOINTER*/CNativeBuffer TargetValue,
     /*SQLLEN*/IntPtr BufferLength, // sql.h differs from MSDN
     /*SQLLEN* */out IntPtr StrLen_or_Ind);
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLFreeStmt(
     /*SQLHSTMT*/OdbcStatementHandle  StatementHandle,
     /*SQLUSMALLINT*/ODBC32.STMT Option);
        internal OdbcHandle(OdbcStatementHandle parentHandle, ODBC32.SQL_ATTR attribute) : base(IntPtr.Zero, true) {
            Debug.Assert((ODBC32.SQL_ATTR.APP_PARAM_DESC == attribute) || (ODBC32.SQL_ATTR.APP_ROW_DESC == attribute), "invalid attribute");
            _handleType   = ODBC32.SQL_HANDLE.DESC;

            int cbActual;
            ODBC32.RetCode retcode;
            bool mustRelease = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                // must addref before calling native so it won't be released just after
                parentHandle.DangerousAddRef(ref mustRelease);

                retcode = parentHandle.GetStatementAttribute(attribute, out base.handle, out cbActual);
            }
            finally {
                if (mustRelease) {
                    if (IntPtr.Zero != base.handle) {
                        // must call DangerousAddRef after a handle is actually created
                        // since ReleaseHandle will only call DangerousRelease if a handle exists
                        _parentHandle = parentHandle;
                    }
                    else {
                        // without a handle, ReleaseHandle may not be called
                        parentHandle.DangerousRelease();
                    }
                }
            }
            if (ADP.PtrZero == base.handle) {
                throw ODBC.FailedToGetDescriptorHandle(retcode);
            }
            // no info-message handle on getting a descriptor handle
        }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLCancel(
     /*SQLHSTMT*/OdbcStatementHandle StatementHandle);
Exemple #36
0
 internal void CreateStatementHandle()
 {
     this.DisposeStatementHandle();
     this._stmt = this._connection.CreateStatementHandle();
 }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLCloseCursor(
     /*SQLHSTMT*/OdbcStatementHandle StatementHandle);
        private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, string method, bool needReader, object[] methodArguments, ODBC32.SQL_API odbcApiMethod)
        {
            OdbcDataReader target = null;

            try
            {
                ODBC32.RetCode typeInfo;
                this.DisposeDeadDataReader();
                this.ValidateConnectionAndTransaction(method);
                if ((CommandBehavior.SingleRow & behavior) != CommandBehavior.Default)
                {
                    behavior |= CommandBehavior.SingleResult;
                }
                OdbcStatementHandle statementHandle = this.GetStatementHandle().StatementHandle;
                this._cmdWrapper.Canceling = false;
                if ((this.weakDataReaderReference != null) && this.weakDataReaderReference.IsAlive)
                {
                    object obj2 = this.weakDataReaderReference.Target;
                    if (((obj2 != null) && this.weakDataReaderReference.IsAlive) && !((OdbcDataReader)obj2).IsClosed)
                    {
                        throw ADP.OpenReaderExists();
                    }
                }
                target = new OdbcDataReader(this, this._cmdWrapper, behavior);
                if (!this.Connection.ProviderInfo.NoQueryTimeout)
                {
                    this.TrySetStatementAttribute(statementHandle, ODBC32.SQL_ATTR.QUERY_TIMEOUT, (IntPtr)this.CommandTimeout);
                }
                if ((needReader && this.Connection.IsV3Driver) && (!this.Connection.ProviderInfo.NoSqlSoptSSNoBrowseTable && !this.Connection.ProviderInfo.NoSqlSoptSSHiddenColumns))
                {
                    if (target.IsBehavior(CommandBehavior.KeyInfo))
                    {
                        if (!this._cmdWrapper._ssKeyInfoModeOn)
                        {
                            this.TrySetStatementAttribute(statementHandle, (ODBC32.SQL_ATTR) 0x4cc, (IntPtr)1L);
                            this.TrySetStatementAttribute(statementHandle, ODBC32.SQL_ATTR.SQL_COPT_SS_TXN_ISOLATION, (IntPtr)1L);
                            this._cmdWrapper._ssKeyInfoModeOff = false;
                            this._cmdWrapper._ssKeyInfoModeOn  = true;
                        }
                    }
                    else if (!this._cmdWrapper._ssKeyInfoModeOff)
                    {
                        this.TrySetStatementAttribute(statementHandle, (ODBC32.SQL_ATTR) 0x4cc, (IntPtr)0L);
                        this.TrySetStatementAttribute(statementHandle, ODBC32.SQL_ATTR.SQL_COPT_SS_TXN_ISOLATION, (IntPtr)0L);
                        this._cmdWrapper._ssKeyInfoModeOff = true;
                        this._cmdWrapper._ssKeyInfoModeOn  = false;
                    }
                }
                if (target.IsBehavior(CommandBehavior.KeyInfo) || target.IsBehavior(CommandBehavior.SchemaOnly))
                {
                    typeInfo = statementHandle.Prepare(this.CommandText);
                    if (typeInfo != ODBC32.RetCode.SUCCESS)
                    {
                        this._connection.HandleError(statementHandle, typeInfo);
                    }
                }
                bool          success         = false;
                CNativeBuffer parameterBuffer = this._cmdWrapper._nativeParameterBuffer;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    if ((this._parameterCollection != null) && (0 < this._parameterCollection.Count))
                    {
                        int initialSize = this._parameterCollection.CalcParameterBufferSize(this);
                        if ((parameterBuffer == null) || (parameterBuffer.Length < initialSize))
                        {
                            if (parameterBuffer != null)
                            {
                                parameterBuffer.Dispose();
                            }
                            parameterBuffer = new CNativeBuffer(initialSize);
                            this._cmdWrapper._nativeParameterBuffer = parameterBuffer;
                        }
                        else
                        {
                            parameterBuffer.ZeroMemory();
                        }
                        parameterBuffer.DangerousAddRef(ref success);
                        this._parameterCollection.Bind(this, this._cmdWrapper, parameterBuffer);
                    }
                    if (target.IsBehavior(CommandBehavior.SchemaOnly))
                    {
                        goto Label_0443;
                    }
                    if ((target.IsBehavior(CommandBehavior.KeyInfo) || target.IsBehavior(CommandBehavior.SchemaOnly)) && (this.CommandType != System.Data.CommandType.StoredProcedure))
                    {
                        short num2;
                        typeInfo = statementHandle.NumberOfResultColumns(out num2);
                        switch (typeInfo)
                        {
                        case ODBC32.RetCode.SUCCESS:
                        case ODBC32.RetCode.SUCCESS_WITH_INFO:
                            if (num2 > 0)
                            {
                                target.GetSchemaTable();
                            }
                            goto Label_029A;
                        }
                        if (typeInfo != ODBC32.RetCode.NO_DATA)
                        {
                            this._connection.HandleError(statementHandle, typeInfo);
                        }
                    }
Label_029A:
                    switch (odbcApiMethod)
                    {
                    case ODBC32.SQL_API.SQLEXECDIRECT:
                        if (target.IsBehavior(CommandBehavior.KeyInfo) || this._isPrepared)
                        {
                            typeInfo = statementHandle.Execute();
                        }
                        else
                        {
                            typeInfo = statementHandle.ExecuteDirect(this.CommandText);
                        }
                        break;

                    case ODBC32.SQL_API.SQLCOLUMNS:
                        typeInfo = statementHandle.Columns((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (string)methodArguments[3]);
                        break;

                    case ODBC32.SQL_API.SQLSTATISTICS:
                        typeInfo = statementHandle.Statistics((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (short)methodArguments[3], (short)methodArguments[4]);
                        break;

                    case ODBC32.SQL_API.SQLTABLES:
                        typeInfo = statementHandle.Tables((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (string)methodArguments[3]);
                        break;

                    case ODBC32.SQL_API.SQLGETTYPEINFO:
                        typeInfo = statementHandle.GetTypeInfo((short)methodArguments[0]);
                        break;

                    case ODBC32.SQL_API.SQLPROCEDURECOLUMNS:
                        typeInfo = statementHandle.ProcedureColumns((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (string)methodArguments[3]);
                        break;

                    case ODBC32.SQL_API.SQLPROCEDURES:
                        typeInfo = statementHandle.Procedures((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2]);
                        break;

                    default:
                        throw ADP.InvalidOperation(method.ToString());
                    }
                    if ((typeInfo != ODBC32.RetCode.SUCCESS) && (ODBC32.RetCode.NO_DATA != typeInfo))
                    {
                        this._connection.HandleError(statementHandle, typeInfo);
                    }
                }
                finally
                {
                    if (success)
                    {
                        parameterBuffer.DangerousRelease();
                    }
                }
Label_0443:
                this.weakDataReaderReference = new WeakReference(target);
                if (!target.IsBehavior(CommandBehavior.SchemaOnly))
                {
                    target.FirstResult();
                }
                this.cmdState = ConnectionState.Fetching;
            }
            finally
            {
                if (ConnectionState.Fetching != this.cmdState)
                {
                    if (target != null)
                    {
                        if (this._parameterCollection != null)
                        {
                            this._parameterCollection.ClearBindings();
                        }
                        target.Dispose();
                    }
                    if (this.cmdState != ConnectionState.Closed)
                    {
                        this.cmdState = ConnectionState.Closed;
                    }
                }
            }
            return(target);
        }
 internal void Bind(OdbcStatementHandle hstmt, OdbcCommand command, short ordinal, CNativeBuffer parameterBuffer, bool allowReentrance)
 {
     ODBC32.SQL_C sql_c = this._prepared_Sql_C_Type;
     ODBC32.SQL_PARAM sql_param = this.SqlDirectionFromParameterDirection();
     int offset = this._preparedOffset;
     int sizeorprecision = this._preparedSize;
     object obj2 = this._preparedValue;
     int valueSize = this.GetValueSize(obj2, offset);
     int num4 = this.GetColumnSize(obj2, offset, ordinal);
     byte parameterPrecision = this.GetParameterPrecision(obj2);
     byte parameterScale = this.GetParameterScale(obj2);
     HandleRef buffer = parameterBuffer.PtrOffset(this._preparedValueOffset, this._preparedBufferSize);
     HandleRef intbuffer = parameterBuffer.PtrOffset(this._preparedIntOffset, IntPtr.Size);
     if (ODBC32.SQL_C.NUMERIC == sql_c)
     {
         if (((ODBC32.SQL_PARAM.INPUT_OUTPUT == sql_param) && (obj2 is decimal)) && (parameterScale < this._internalScale))
         {
             while (parameterScale < this._internalScale)
             {
                 obj2 = ((decimal) obj2) * 10M;
                 parameterScale = (byte) (parameterScale + 1);
             }
         }
         this.SetInputValue(obj2, sql_c, valueSize, parameterPrecision, 0, parameterBuffer);
         if (ODBC32.SQL_PARAM.INPUT != sql_param)
         {
             parameterBuffer.WriteInt16(this._preparedValueOffset, (short) ((parameterScale << 8) | parameterPrecision));
         }
     }
     else
     {
         this.SetInputValue(obj2, sql_c, valueSize, sizeorprecision, offset, parameterBuffer);
     }
     if (((this._hasChanged || (this._boundSqlCType != sql_c)) || ((this._boundParameterType != this._bindtype._sql_type) || (this._boundSize != num4))) || (((this._boundScale != parameterScale) || (this._boundBuffer != buffer.Handle)) || (this._boundIntbuffer != intbuffer.Handle)))
     {
         ODBC32.RetCode retcode = hstmt.BindParameter(ordinal, (short) sql_param, sql_c, this._bindtype._sql_type, (IntPtr) num4, (IntPtr) parameterScale, buffer, (IntPtr) this._preparedBufferSize, intbuffer);
         if (retcode != ODBC32.RetCode.SUCCESS)
         {
             if ("07006" == command.GetDiagSqlState())
             {
                 Bid.Trace("<odbc.OdbcParameter.Bind|ERR> Call to BindParameter returned errorcode [07006]\n");
                 command.Connection.FlagRestrictedSqlBindType(this._bindtype._sql_type);
                 if (allowReentrance)
                 {
                     this.Bind(hstmt, command, ordinal, parameterBuffer, false);
                     return;
                 }
             }
             command.Connection.HandleError(hstmt, retcode);
         }
         this._hasChanged = false;
         this._boundSqlCType = sql_c;
         this._boundParameterType = this._bindtype._sql_type;
         this._boundSize = num4;
         this._boundScale = parameterScale;
         this._boundBuffer = buffer.Handle;
         this._boundIntbuffer = intbuffer.Handle;
         if (ODBC32.SQL_C.NUMERIC == sql_c)
         {
             OdbcDescriptorHandle descriptorHandle = command.GetDescriptorHandle(ODBC32.SQL_ATTR.APP_PARAM_DESC);
             retcode = descriptorHandle.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.TYPE, (IntPtr) 2L);
             if (retcode != ODBC32.RetCode.SUCCESS)
             {
                 command.Connection.HandleError(hstmt, retcode);
             }
             int num2 = parameterPrecision;
             retcode = descriptorHandle.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.PRECISION, (IntPtr) num2);
             if (retcode != ODBC32.RetCode.SUCCESS)
             {
                 command.Connection.HandleError(hstmt, retcode);
             }
             num2 = parameterScale;
             retcode = descriptorHandle.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.SCALE, (IntPtr) num2);
             if (retcode != ODBC32.RetCode.SUCCESS)
             {
                 command.Connection.HandleError(hstmt, retcode);
             }
             retcode = descriptorHandle.SetDescriptionField2(ordinal, ODBC32.SQL_DESC.DATA_PTR, buffer);
             if (retcode != ODBC32.RetCode.SUCCESS)
             {
                 command.Connection.HandleError(hstmt, retcode);
             }
         }
     }
 }
Exemple #40
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 common case of using no parameters.
                    if ((null != _parameterCollection) && (0 < _parameterCollection.Count))
                    {
                        int parameterBufferSize = _parameterCollection.CalcParameterBufferSize(this);

                        if (null == parameterBuffer || parameterBuffer.Length < parameterBufferSize)
                        {
                            if (null != parameterBuffer)
                            {
                                parameterBuffer.Dispose();
                            }
                            parameterBuffer = new CNativeBuffer(parameterBufferSize);
                            _cmdWrapper._nativeParameterBuffer = parameterBuffer;
                        }
                        else
                        {
                            parameterBuffer.ZeroMemory();
                        }

                        parameterBuffer.DangerousAddRef(ref mustRelease);

                        _parameterCollection.Bind(this, _cmdWrapper, parameterBuffer);
                    }

                    if (!localReader.IsBehavior(CommandBehavior.SchemaOnly))
                    {
                        // Can't get the KeyInfo after command execution (SQL Server only since it does not support multiple
                        // results on the same connection). Stored procedures (SP) do not return metadata before actual execution
                        // Need to check the column count since the command type may not be set to SP for a SP.
                        if ((localReader.IsBehavior(CommandBehavior.KeyInfo) || localReader.IsBehavior(CommandBehavior.SchemaOnly)) &&
                            (CommandType != CommandType.StoredProcedure))
                        {
                            short cColsAffected;
                            retcode = stmt.NumberOfResultColumns(out cColsAffected);
                            if (retcode == ODBC32.RetCode.SUCCESS || retcode == ODBC32.RetCode.SUCCESS_WITH_INFO)
                            {
                                if (cColsAffected > 0)
                                {
                                    localReader.GetSchemaTable();
                                }
                            }
                            else if (retcode == ODBC32.RetCode.NO_DATA)
                            {
                                // do nothing
                            }
                            else
                            {
                                // any other returncode indicates an error
                                _connection.HandleError(stmt, retcode);
                            }
                        }

                        switch (odbcApiMethod)
                        {
                        case ODBC32.SQL_API.SQLEXECDIRECT:
                            if (localReader.IsBehavior(CommandBehavior.KeyInfo) || _isPrepared)
                            {
                                //Already prepared, so use SQLExecute
                                retcode = stmt.Execute();
                                // Build metadata here
                                // localReader.GetSchemaTable();
                            }
                            else
                            {
#if DEBUG
                                //if (AdapterSwitches.OleDbTrace.TraceInfo) {
                                //    ADP.DebugWriteLine("SQLExecDirectW: " + CommandText);
                                //}
#endif
                                //SQLExecDirect
                                retcode = stmt.ExecuteDirect(CommandText);
                            }
                            break;

                        case ODBC32.SQL_API.SQLTABLES:
                            retcode = stmt.Tables((string)methodArguments[0],  //TableCatalog
                                                  (string)methodArguments[1],  //TableSchema,
                                                  (string)methodArguments[2],  //TableName
                                                  (string)methodArguments[3]); //TableType
                            break;

                        case ODBC32.SQL_API.SQLCOLUMNS:
                            retcode = stmt.Columns((string)methodArguments[0],  //TableCatalog
                                                   (string)methodArguments[1],  //TableSchema
                                                   (string)methodArguments[2],  //TableName
                                                   (string)methodArguments[3]); //ColumnName
                            break;

                        case ODBC32.SQL_API.SQLPROCEDURES:
                            retcode = stmt.Procedures((string)methodArguments[0],  //ProcedureCatalog
                                                      (string)methodArguments[1],  //ProcedureSchema
                                                      (string)methodArguments[2]); //procedureName
                            break;

                        case ODBC32.SQL_API.SQLPROCEDURECOLUMNS:
                            retcode = stmt.ProcedureColumns((string)methodArguments[0],  //ProcedureCatalog
                                                            (string)methodArguments[1],  //ProcedureSchema
                                                            (string)methodArguments[2],  //procedureName
                                                            (string)methodArguments[3]); //columnName
                            break;

                        case ODBC32.SQL_API.SQLSTATISTICS:
                            retcode = stmt.Statistics((string)methodArguments[0], //TableCatalog
                                                      (string)methodArguments[1], //TableSchema
                                                      (string)methodArguments[2], //TableName
                                                      (short)methodArguments[3],  //IndexTrpe
                                                      (short)methodArguments[4]); //Accuracy
                            break;

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

                        default:
                            // this should NEVER happen
                            Debug.Fail("ExecuteReaderObjectcalled with unsupported ODBC API method.");
                            throw ADP.InvalidOperation(method.ToString());
                        }

                        //Note: Execute will return NO_DATA for Update/Delete non-row returning queries
                        if ((ODBC32.RetCode.SUCCESS != retcode) && (ODBC32.RetCode.NO_DATA != retcode))
                        {
                            _connection.HandleError(stmt, retcode);
                        }
                    } // end SchemaOnly
                }
                finally
                {
                    if (mustRelease)
                    {
                        parameterBuffer.DangerousRelease();
                    }
                }

                _weakDataReaderReference = new WeakReference(localReader);

                // XXXCommand.Execute should position reader on first row returning result
                // any exceptions in the initial non-row returning results should be thrown
                // from ExecuteXXX not the DataReader
                if (!localReader.IsBehavior(CommandBehavior.SchemaOnly))
                {
                    localReader.FirstResult();
                }
                _cmdState = ConnectionState.Fetching;
            }
            finally
            {
                if (ConnectionState.Fetching != _cmdState)
                {
                    if (null != localReader)
                    {
                        // clear bindings so we don't grab output parameters on a failed execute
                        if (null != _parameterCollection)
                        {
                            _parameterCollection.ClearBindings();
                        }
                        ((IDisposable)localReader).Dispose();
                    }
                    if (ConnectionState.Closed != _cmdState)
                    {
                        _cmdState = ConnectionState.Closed;
                    }
                }
            }
            return(localReader);
        }
        internal void Bind(OdbcStatementHandle hstmt, OdbcCommand command, short ordinal, CNativeBuffer parameterBuffer, bool allowReentrance) {
            ODBC32.RetCode  retcode;
            ODBC32.SQL_C    sql_c_type = _prepared_Sql_C_Type;
            ODBC32.SQL_PARAM sqldirection = SqlDirectionFromParameterDirection();

            int offset      = _preparedOffset;
            int size        = _preparedSize;
            object value    = _preparedValue;
            int cbValueSize = GetValueSize(value, offset);             // count of bytes for the data
            int cchSize     = GetColumnSize(value, offset, ordinal);   // count of bytes for the data, used to allocate the buffer length
            byte precision  = GetParameterPrecision(value);
            byte scale      = GetParameterScale(value);
            int cbActual;

            HandleRef valueBuffer  = parameterBuffer.PtrOffset(_preparedValueOffset, _preparedBufferSize);
            HandleRef intBuffer    = parameterBuffer.PtrOffset(_preparedIntOffset, IntPtr.Size);

            // for the numeric datatype we need to do some special case handling ...
            //
            if (ODBC32.SQL_C.NUMERIC == sql_c_type) {

                // for input/output parameters we need to adjust the scale of the input value since the convert function in
                // sqlsrv32 takes this scale for the output parameter (possible bug in sqlsrv32?)
                //
                if ((ODBC32.SQL_PARAM.INPUT_OUTPUT == sqldirection) && (value is Decimal)) {
                    if (scale < _internalScale) {
                        while (scale < _internalScale) {
                            value = ((decimal)value ) * 10;
                            scale++;
                        }
                    }
                }
                SetInputValue(value, sql_c_type, cbValueSize, precision, 0, parameterBuffer);

                // for output parameters we need to write precision and scale to the buffer since the convert function in
                // sqlsrv32 expects these values there (possible bug in sqlsrv32?)
                //
                if (ODBC32.SQL_PARAM.INPUT != sqldirection) {
                    parameterBuffer.WriteInt16(_preparedValueOffset, (short)(((ushort)scale << 8) | (ushort)precision));
                }
            }
            else {
                SetInputValue(value, sql_c_type, cbValueSize, size, offset, parameterBuffer);
            }


            // Try to reuse existing bindings if
            //  the binding is valid (means we already went through binding all parameters)
            //  the parametercollection is bound already
            //  the bindtype ParameterType did not change (forced upgrade)

            if (!_hasChanged
                && (_boundSqlCType == sql_c_type)
                && (_boundParameterType == _bindtype._sql_type)
                && (_boundSize == cchSize)
                && (_boundScale == scale)
                && (_boundBuffer == valueBuffer.Handle)
                && (_boundIntbuffer == intBuffer.Handle)
            ) {
                return;
            }

            //SQLBindParameter
            retcode = hstmt.BindParameter(
                                    ordinal,                    // Parameter Number
                                    (short)sqldirection,        // InputOutputType
                                    sql_c_type,                 // ValueType
                                    _bindtype._sql_type,        // ParameterType
                                    (IntPtr)cchSize,            // ColumnSize
                                    (IntPtr)scale,              // DecimalDigits
                                    valueBuffer,                // ParameterValuePtr
                                    (IntPtr)_preparedBufferSize,
                                    intBuffer);                 // StrLen_or_IndPtr

            if (ODBC32.RetCode.SUCCESS != retcode) {
                if ("07006" == command.GetDiagSqlState()) {
                    Bid.Trace("<odbc.OdbcParameter.Bind|ERR> Call to BindParameter returned errorcode [07006]\n");
                    command.Connection.FlagRestrictedSqlBindType(_bindtype._sql_type);
                    if (allowReentrance) {
                        this.Bind(hstmt, command, ordinal, parameterBuffer, false);
                        return;
                    }
                }
                command.Connection.HandleError(hstmt, retcode);
            }
            _hasChanged = false;
            _boundSqlCType = sql_c_type;
            _boundParameterType = _bindtype._sql_type;
            _boundSize = cchSize;
            _boundScale = scale;
            _boundBuffer = valueBuffer.Handle;
            _boundIntbuffer = intBuffer.Handle;

            if (ODBC32.SQL_C.NUMERIC == sql_c_type) {
                OdbcDescriptorHandle hdesc = command.GetDescriptorHandle(ODBC32.SQL_ATTR.APP_PARAM_DESC);
                // descriptor handle is cached on command wrapper, don't release it

                // Set descriptor Type
                //
                //SQLSetDescField(hdesc, i+1, SQL_DESC_TYPE, (void *)SQL_C_NUMERIC, 0);
                retcode = hdesc.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.TYPE, (IntPtr)ODBC32.SQL_C.NUMERIC);

                if (ODBC32.RetCode.SUCCESS != retcode) {
                    command.Connection.HandleError(hstmt, retcode);
                }


                // Set precision
                //
                cbActual= (int)precision;
                //SQLSetDescField(hdesc, i+1, SQL_DESC_PRECISION, (void *)precision, 0);
                retcode = hdesc.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.PRECISION, (IntPtr)cbActual);

                if (ODBC32.RetCode.SUCCESS != retcode) {
                    command.Connection.HandleError(hstmt, retcode);
                }


                // Set scale
                //
                // SQLSetDescField(hdesc, i+1, SQL_DESC_SCALE,  (void *)llen, 0);
                cbActual= (int)scale;
                retcode = hdesc.SetDescriptionField1(ordinal, ODBC32.SQL_DESC.SCALE, (IntPtr)cbActual);

                if (ODBC32.RetCode.SUCCESS != retcode) {
                    command.Connection.HandleError(hstmt, retcode);
                }

                // Set data pointer
                //
                // SQLSetDescField(hdesc, i+1, SQL_DESC_DATA_PTR,  (void *)&numeric, 0);
                retcode = hdesc.SetDescriptionField2(ordinal, ODBC32.SQL_DESC.DATA_PTR, valueBuffer);

                if (ODBC32.RetCode.SUCCESS != retcode) {
                    command.Connection.HandleError(hstmt, retcode);
                }
            }
        }
        void TrySetStatementAttribute (OdbcStatementHandle stmt, ODBC32.SQL_ATTR stmtAttribute, IntPtr value) {

            ODBC32.RetCode retcode = stmt.SetStatementAttribute(
                stmtAttribute,
                value,
                ODBC32.SQL_IS.UINTEGER);

            if (retcode == ODBC32.RetCode.ERROR) {

                string sqlState;
                stmt.GetDiagnosticField(out sqlState);

                if ((sqlState == "HYC00") || (sqlState == "HY092")) {
                    Connection.FlagUnsupportedStmtAttr(stmtAttribute);
                }
                else {
                    // now what? Should we throw?
                }
            }
        }
Exemple #43
0
 internal void CreateStatementHandle()
 {
     DisposeStatementHandle();
     _stmt = _connection.CreateStatementHandle();
 }
        internal void FreeStatementHandle(ODBC32.STMT stmt) {
            DisposeDescriptorHandle();

            OdbcStatementHandle handle = _stmt;
            if (null != handle) {
                try {
                    ODBC32.RetCode retcode;
                    retcode = handle.FreeStatement(stmt);
                    StatementErrorHandler(retcode);
                }
                catch (Exception e) {
                    // 
                    if (ADP.IsCatchableExceptionType(e)) {
                        _stmt = null;
                        handle.Dispose();
                    }

                    throw;
                }
            }
        }
Exemple #45
0
 internal void CreateKeyInfoStatementHandle()
 {
     this.DisposeKeyInfoStatementHandle();
     this._keyinfostmt = this._connection.CreateStatementHandle();
 }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLSetStmtAttrW(
     /*SQLHSTMT*/OdbcStatementHandle          StatementHandle,
     /*SQLINTEGER*/Int32      Attribute,
     /*SQLPOINTER*/IntPtr     Value,
     /*SQLINTEGER*/Int32      StringLength);
Exemple #47
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);
                    }
                }
            }
        }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLSpecialColumnsW (
     /*SQLHSTMT*/OdbcStatementHandle StatementHandle,
     /*SQLUSMALLINT*/ODBC32.SQL_SPECIALCOLS IdentifierType,
     [In, MarshalAs(UnmanagedType.LPWStr)]
     /*SQLCHAR* */string CatalogName,
     /*SQLSMALLINT*/Int16 NameLen1,
     [In, MarshalAs(UnmanagedType.LPWStr)]
     /*SQLCHAR* */string SchemaName,
     /*SQLSMALLINT*/Int16 NameLen2,
     [In, MarshalAs(UnmanagedType.LPWStr)]
     /*SQLCHAR* */string TableName,
     /*SQLSMALLINT*/Int16 NameLen3,
     /*SQLUSMALLINT*/ODBC32.SQL_SCOPE Scope,
     /*SQLUSMALLINT*/ ODBC32.SQL_NULLABILITY Nullable);
 internal void FreeKeyInfoStatementHandle(ODBC32.STMT stmt)
 {
     OdbcStatementHandle handle = this._keyinfostmt;
     if (handle != null)
     {
         try
         {
             handle.FreeStatement(stmt);
         }
         catch (Exception exception)
         {
             if (ADP.IsCatchableExceptionType(exception))
             {
                 this._keyinfostmt = null;
                 handle.Dispose();
             }
             throw;
         }
     }
 }
        internal void FreeKeyInfoStatementHandle(ODBC32.STMT stmt) {
            OdbcStatementHandle handle = _keyinfostmt;
            if (null != handle) {
                try {
                    handle.FreeStatement(stmt);
                }
                catch (Exception e) {
                    // 
                    if (ADP.IsCatchableExceptionType(e)) {
                        _keyinfostmt = null;
                        handle.Dispose();
                    }

                    throw;
                }
            }
        }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLGetTypeInfo(
     /*SQLHSTMT*/OdbcStatementHandle  StatementHandle,
     /*SQLSMALLINT*/Int16 fSqlType);
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLRowCount(
     /*SQLHSTMT*/OdbcStatementHandle  StatementHandle,
     /*SQLLEN* */out IntPtr RowCount);
Exemple #53
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);
                }
            }
        }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLMoreResults(
     /*SQLHSTMT*/OdbcStatementHandle  StatementHandle);
Exemple #55
0
 internal OdbcDescriptorHandle(OdbcStatementHandle statementHandle, ODBC32.SQL_ATTR attribute) : base(statementHandle, attribute)
 {
 }
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLNumResultCols(
     /*SQLHSTMT*/OdbcStatementHandle  StatementHandle,
     /*SQLSMALLINT* */out Int16 ColumnCount);
Exemple #57
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;
 static internal extern /*SQLRETURN*/ODBC32.RetCode SQLPrepareW(
     /*SQLHSTMT*/OdbcStatementHandle  StatementHandle,
     [In, MarshalAs(UnmanagedType.LPWStr)]
     /*SQLCHAR* */string   StatementText,
     /*SQLINTEGER*/Int32 TextLength);