コード例 #1
0
        void RefreshSchema()
        {
            // creates metadata
            if (SelectCommand == null)
            {
                throw new InvalidOperationException("SelectCommand should be valid");
            }
            if (SelectCommand.Connection == null)
            {
                throw new InvalidOperationException("SelectCommand's Connection should be valid");
            }

            CommandBehavior behavior = CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo;

            if (SelectCommand.Connection.State != ConnectionState.Open)
            {
                SelectCommand.Connection.Open();
                behavior |= CommandBehavior.CloseConnection;
            }

            OdbcDataReader reader = SelectCommand.ExecuteReader(behavior);

            _schema = reader.GetSchemaTable();
            reader.Close();

            // force creation of commands
            _insertCommand = null;
            _updateCommand = null;
            _deleteCommand = null;
            _tableName     = String.Empty;
        }
コード例 #2
0
ファイル: OdbcCommand.cs プロジェクト: zdbobi/runtime
        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;
コード例 #3
0
        private void DataTableFromDataReaderDataTypes(DataTable dataTypesTable, OdbcDataReader dataReader, OdbcConnection connection) {

            DataTable       schemaTable = null;
            // 

            // Build a DataTable from the reader
            schemaTable = dataReader.GetSchemaTable();

            // vstfdevdiv:479715 Handle cases where reader is empty
            if (null == schemaTable) {
                throw ADP.OdbcNoTypesFromProvider();
            }
            
            object[] getTypeInfoValues = new object[schemaTable.Rows.Count];
            DataRow dataTypesRow;

            DataColumn typeNameColumn = dataTypesTable.Columns[DbMetaDataColumnNames.TypeName];
            DataColumn providerDbTypeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.ProviderDbType];
            DataColumn columnSizeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.ColumnSize];
            DataColumn createParametersColumn = dataTypesTable.Columns[DbMetaDataColumnNames.CreateParameters];
            DataColumn dataTypeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.DataType];
            DataColumn isAutoIncermentableColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsAutoIncrementable];
            DataColumn isCaseSensitiveColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsCaseSensitive];
            DataColumn isFixedLengthColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength];
            DataColumn isFixedPrecisionScaleColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedPrecisionScale];
            DataColumn isLongColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsLong];
            DataColumn isNullableColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsNullable];
            DataColumn isSearchableColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchable];
            DataColumn isSearchableWithLikeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchableWithLike];
            DataColumn isUnsignedColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsUnsigned];
            DataColumn maximumScaleColumn = dataTypesTable.Columns[DbMetaDataColumnNames.MaximumScale];
            DataColumn minimumScaleColumn = dataTypesTable.Columns[DbMetaDataColumnNames.MinimumScale];
            DataColumn literalPrefixColumn = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralPrefix];
            DataColumn literalSuffixColumn = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralSuffix];
            DataColumn SQLTypeNameColumn = dataTypesTable.Columns[OdbcMetaDataColumnNames.SQLType];


            const int indexTYPE_NAME = 0;
            const int indexDATA_TYPE = 1;
            const int indexCOLUMN_SIZE = 2;
            const int indexCREATE_PARAMS = 5;
            const int indexAUTO_UNIQUE_VALUE = 11;
            const int indexCASE_SENSITIVE = 7;
            const int indexFIXED_PREC_SCALE = 10;
            const int indexNULLABLE = 6;
            const int indexSEARCHABLE = 8;
            const int indexUNSIGNED_ATTRIBUTE = 9;
            const int indexMAXIMUM_SCALE = 14;
            const int indexMINIMUM_SCALE = 13;
            const int indexLITERAL_PREFIX = 3;
            const int indexLITERAL_SUFFIX = 4;

            const int SQL_DATE_V2 = 9;
            const int SQL_TIME_V2 = 10;

            TypeMap typeMap ;


            while (dataReader.Read()) {
                dataReader.GetValues(getTypeInfoValues);
                dataTypesRow = dataTypesTable.NewRow();

                ODBC32.SQL_TYPE sqlType;

                dataTypesRow[typeNameColumn] = getTypeInfoValues[indexTYPE_NAME];
                dataTypesRow[SQLTypeNameColumn] = getTypeInfoValues[indexDATA_TYPE];

                sqlType = (ODBC32.SQL_TYPE)(Int32) Convert.ChangeType(getTypeInfoValues[indexDATA_TYPE],
                                                                      typeof(Int32), 
                                                                      (System.IFormatProvider)null);
                // if the driver is pre version 3 and it returned the v2 SQL_DATE or SQL_TIME types they need
                // to be mapped to thier v3 equlivants
                if (connection.IsV3Driver == false) {
                    if ((int)sqlType == SQL_DATE_V2) {
                        sqlType = ODBC32.SQL_TYPE.TYPE_DATE;
                    }
                    else if ((int)sqlType == SQL_TIME_V2) {
                        sqlType = ODBC32.SQL_TYPE.TYPE_TIME;
                    }
                }
                try {
                   typeMap = TypeMap.FromSqlType(sqlType);
                }
                // FromSqlType will throw an argument exception if it does not recognize the SqlType.
                // This is not an error since the GetTypeInfo DATA_TYPE may be a SQL data type or a driver specific
                // type. If there is no TypeMap for the type its not an error but it will degrade our level of
                // understanding of/ support for the type.
                catch (ArgumentException) {
                    typeMap = null;
                }

                // if we have a type map we can determine the dbType and the CLR type if not leave them null
                if (typeMap != null) {
                    dataTypesRow[providerDbTypeColumn] = typeMap._odbcType;
                    dataTypesRow[dataTypeColumn] = typeMap._type.FullName;
                    // setting isLong and isFixedLength only if we have a type map because for provider
                    // specific types we have no idea what the types attributes are if GetTypeInfo did not
                    // tell us
                    switch (sqlType) {

                        case ODBC32.SQL_TYPE.LONGVARCHAR:
                        case ODBC32.SQL_TYPE.WLONGVARCHAR:
                        case ODBC32.SQL_TYPE.LONGVARBINARY:
                        case ODBC32.SQL_TYPE.SS_XML:
                            dataTypesRow[isLongColumn] = true;
                            dataTypesRow[isFixedLengthColumn] = false;
                            break;

                        case ODBC32.SQL_TYPE.VARCHAR:
                        case ODBC32.SQL_TYPE.WVARCHAR:
                        case ODBC32.SQL_TYPE.VARBINARY:
                            dataTypesRow[isLongColumn] = false;
                            dataTypesRow[isFixedLengthColumn] = false;
                            break;

                        case ODBC32.SQL_TYPE.CHAR:
                        case ODBC32.SQL_TYPE.WCHAR:
                        case ODBC32.SQL_TYPE.DECIMAL:
                        case ODBC32.SQL_TYPE.NUMERIC:
                        case ODBC32.SQL_TYPE.SMALLINT:
                        case ODBC32.SQL_TYPE.INTEGER:
                        case ODBC32.SQL_TYPE.REAL:
                        case ODBC32.SQL_TYPE.FLOAT:
                        case ODBC32.SQL_TYPE.DOUBLE:
                        case ODBC32.SQL_TYPE.BIT:
                        case ODBC32.SQL_TYPE.TINYINT:
                        case ODBC32.SQL_TYPE.BIGINT:
                        case ODBC32.SQL_TYPE.TYPE_DATE:
                        case ODBC32.SQL_TYPE.TYPE_TIME:
                        case ODBC32.SQL_TYPE.TIMESTAMP:
                        case ODBC32.SQL_TYPE.TYPE_TIMESTAMP:
                        case ODBC32.SQL_TYPE.GUID:
                        case ODBC32.SQL_TYPE.SS_VARIANT:
                        case ODBC32.SQL_TYPE.SS_UTCDATETIME:
                        case ODBC32.SQL_TYPE.SS_TIME_EX:
                        case ODBC32.SQL_TYPE.BINARY:    
                            dataTypesRow[isLongColumn] = false;
                            dataTypesRow[isFixedLengthColumn] = true;
                            break;

                        case ODBC32.SQL_TYPE.SS_UDT:
                        default:
                            // for User defined types don't know if its long or or if it is
                            // varaible length or not so leave the fields null
                            break;
                    }
                }



                dataTypesRow[columnSizeColumn] = getTypeInfoValues[indexCOLUMN_SIZE];
                dataTypesRow[createParametersColumn] = getTypeInfoValues[indexCREATE_PARAMS];

                if ((getTypeInfoValues[indexAUTO_UNIQUE_VALUE] == DBNull.Value) ||
                    (Convert.ToInt16(getTypeInfoValues[indexAUTO_UNIQUE_VALUE], null) == 0)) {
                    dataTypesRow[isAutoIncermentableColumn] = false;
                }
                else {
                    dataTypesRow[isAutoIncermentableColumn] = true;
                }

                dataTypesRow[isCaseSensitiveColumn] = BooleanFromODBC(getTypeInfoValues[indexCASE_SENSITIVE]);
                dataTypesRow[isFixedPrecisionScaleColumn] = BooleanFromODBC(getTypeInfoValues[indexFIXED_PREC_SCALE]);

                if (getTypeInfoValues[indexNULLABLE] != DBNull.Value) {
                    //Use Convert.ToInt16 instead of direct cast to short because the value will be Int32 in some cases
                    switch ((ODBC32.SQL_NULLABILITY)Convert.ToInt16(getTypeInfoValues[indexNULLABLE], null)) { 

                        case ODBC32.SQL_NULLABILITY.NO_NULLS:
                            dataTypesRow[isNullableColumn] = false;
                            break;

                        case ODBC32.SQL_NULLABILITY.NULLABLE:
                            dataTypesRow[isNullableColumn] = true;
                            break;

                        case ODBC32.SQL_NULLABILITY.UNKNOWN:
                            dataTypesRow[isNullableColumn] = DBNull.Value;
                            break;
                    }
                }

                if ( DBNull.Value != getTypeInfoValues[indexSEARCHABLE]){

                    //Use Convert.ToInt16 instead of direct cast to short because the value will be Int32 in some cases
                    Int16 searchableValue = Convert.ToInt16(getTypeInfoValues[indexSEARCHABLE], null);
                    switch (searchableValue){

                        case (Int16)ODBC32.SQL_SEARCHABLE.UNSEARCHABLE:
                            dataTypesRow[isSearchableColumn] = false;
                            dataTypesRow[isSearchableWithLikeColumn] = false;
                            break;

                        case (Int16)ODBC32.SQL_SEARCHABLE.LIKE_ONLY:
                             dataTypesRow[isSearchableColumn] = false;
                             dataTypesRow[isSearchableWithLikeColumn] = true;
                             break;

                        case (Int16)ODBC32.SQL_SEARCHABLE.ALL_EXCEPT_LIKE:
                            dataTypesRow[isSearchableColumn] = true;
                            dataTypesRow[isSearchableWithLikeColumn] = false;
                            break;

                        case (Int16)ODBC32.SQL_SEARCHABLE.SEARCHABLE:
                            dataTypesRow[isSearchableColumn] = true;
                            dataTypesRow[isSearchableWithLikeColumn] = true;
                            break;
                    }
                }

                dataTypesRow[isUnsignedColumn] = BooleanFromODBC(getTypeInfoValues[indexUNSIGNED_ATTRIBUTE]);

                //For assignment to the DataSet, don't cast the data types -- let the DataSet take care of any conversion
                if (getTypeInfoValues[indexMAXIMUM_SCALE] != DBNull.Value ) {
                    dataTypesRow[maximumScaleColumn] = getTypeInfoValues[indexMAXIMUM_SCALE];
                }

                if (getTypeInfoValues[indexMINIMUM_SCALE] != DBNull.Value ) {
                    dataTypesRow[minimumScaleColumn] = getTypeInfoValues[indexMINIMUM_SCALE];
                }

                if (getTypeInfoValues[indexLITERAL_PREFIX] != DBNull.Value ) {
                    dataTypesRow[literalPrefixColumn] = getTypeInfoValues[indexLITERAL_PREFIX];
                }

                if (getTypeInfoValues[indexLITERAL_SUFFIX] != DBNull.Value ) {
                    dataTypesRow[literalSuffixColumn] = getTypeInfoValues[indexLITERAL_SUFFIX];
                }

                dataTypesTable.Rows.Add(dataTypesRow);
            }

        }
コード例 #4
0
        private static void DataTableFromDataReaderDataTypes(DataTable dataTypesTable, OdbcDataReader dataReader, OdbcConnection connection)
        {
            DataTable?schemaTable;

            //

            // Build a DataTable from the reader
            schemaTable = dataReader.GetSchemaTable();

            // vstfdevdiv:479715 Handle cases where reader is empty
            if (null == schemaTable)
            {
                throw ADP.OdbcNoTypesFromProvider();
            }

            object[] getTypeInfoValues = new object[schemaTable.Rows.Count];
            DataRow  dataTypesRow;

            DataColumn typeNameColumn              = dataTypesTable.Columns[DbMetaDataColumnNames.TypeName] !;
            DataColumn providerDbTypeColumn        = dataTypesTable.Columns[DbMetaDataColumnNames.ProviderDbType] !;
            DataColumn columnSizeColumn            = dataTypesTable.Columns[DbMetaDataColumnNames.ColumnSize] !;
            DataColumn createParametersColumn      = dataTypesTable.Columns[DbMetaDataColumnNames.CreateParameters] !;
            DataColumn dataTypeColumn              = dataTypesTable.Columns[DbMetaDataColumnNames.DataType] !;
            DataColumn isAutoIncermentableColumn   = dataTypesTable.Columns[DbMetaDataColumnNames.IsAutoIncrementable] !;
            DataColumn isCaseSensitiveColumn       = dataTypesTable.Columns[DbMetaDataColumnNames.IsCaseSensitive] !;
            DataColumn isFixedLengthColumn         = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength] !;
            DataColumn isFixedPrecisionScaleColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedPrecisionScale] !;
            DataColumn isLongColumn               = dataTypesTable.Columns[DbMetaDataColumnNames.IsLong] !;
            DataColumn isNullableColumn           = dataTypesTable.Columns[DbMetaDataColumnNames.IsNullable] !;
            DataColumn isSearchableColumn         = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchable] !;
            DataColumn isSearchableWithLikeColumn = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchableWithLike] !;
            DataColumn isUnsignedColumn           = dataTypesTable.Columns[DbMetaDataColumnNames.IsUnsigned] !;
            DataColumn maximumScaleColumn         = dataTypesTable.Columns[DbMetaDataColumnNames.MaximumScale] !;
            DataColumn minimumScaleColumn         = dataTypesTable.Columns[DbMetaDataColumnNames.MinimumScale] !;
            DataColumn literalPrefixColumn        = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralPrefix] !;
            DataColumn literalSuffixColumn        = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralSuffix] !;
            DataColumn SQLTypeNameColumn          = dataTypesTable.Columns[OdbcMetaDataColumnNames.SQLType] !;


            const int indexTYPE_NAME          = 0;
            const int indexDATA_TYPE          = 1;
            const int indexCOLUMN_SIZE        = 2;
            const int indexCREATE_PARAMS      = 5;
            const int indexAUTO_UNIQUE_VALUE  = 11;
            const int indexCASE_SENSITIVE     = 7;
            const int indexFIXED_PREC_SCALE   = 10;
            const int indexNULLABLE           = 6;
            const int indexSEARCHABLE         = 8;
            const int indexUNSIGNED_ATTRIBUTE = 9;
            const int indexMAXIMUM_SCALE      = 14;
            const int indexMINIMUM_SCALE      = 13;
            const int indexLITERAL_PREFIX     = 3;
            const int indexLITERAL_SUFFIX     = 4;

            const int SQL_DATE_V2 = 9;
            const int SQL_TIME_V2 = 10;

            TypeMap?typeMap;


            while (dataReader.Read())
            {
                dataReader.GetValues(getTypeInfoValues);
                dataTypesRow = dataTypesTable.NewRow();

                ODBC32.SQL_TYPE sqlType;

                dataTypesRow[typeNameColumn]    = getTypeInfoValues[indexTYPE_NAME];
                dataTypesRow[SQLTypeNameColumn] = getTypeInfoValues[indexDATA_TYPE];

                sqlType = (ODBC32.SQL_TYPE)(int) Convert.ChangeType(getTypeInfoValues[indexDATA_TYPE], typeof(int), null);
                // if the driver is pre version 3 and it returned the v2 SQL_DATE or SQL_TIME types they need
                // to be mapped to their v3 equivalent
                if (connection.IsV3Driver == false)
                {
                    if ((int)sqlType == SQL_DATE_V2)
                    {
                        sqlType = ODBC32.SQL_TYPE.TYPE_DATE;
                    }
                    else if ((int)sqlType == SQL_TIME_V2)
                    {
                        sqlType = ODBC32.SQL_TYPE.TYPE_TIME;
                    }
                }
                try
                {
                    typeMap = TypeMap.FromSqlType(sqlType);
                }
                // FromSqlType will throw an argument exception if it does not recognize the SqlType.
                // This is not an error since the GetTypeInfo DATA_TYPE may be a SQL data type or a driver specific
                // type. If there is no TypeMap for the type its not an error but it will degrade our level of
                // understanding of/ support for the type.
                catch (ArgumentException)
                {
                    typeMap = null;
                }

                // if we have a type map we can determine the dbType and the CLR type if not leave them null
                if (typeMap != null)
                {
                    dataTypesRow[providerDbTypeColumn] = typeMap._odbcType;
                    dataTypesRow[dataTypeColumn]       = typeMap._type.FullName;
                    // setting isLong and isFixedLength only if we have a type map because for provider
                    // specific types we have no idea what the types attributes are if GetTypeInfo did not
                    // tell us
                    switch (sqlType)
                    {
                    case ODBC32.SQL_TYPE.LONGVARCHAR:
                    case ODBC32.SQL_TYPE.WLONGVARCHAR:
                    case ODBC32.SQL_TYPE.LONGVARBINARY:
                    case ODBC32.SQL_TYPE.SS_XML:
                        dataTypesRow[isLongColumn]        = true;
                        dataTypesRow[isFixedLengthColumn] = false;
                        break;

                    case ODBC32.SQL_TYPE.VARCHAR:
                    case ODBC32.SQL_TYPE.WVARCHAR:
                    case ODBC32.SQL_TYPE.VARBINARY:
                        dataTypesRow[isLongColumn]        = false;
                        dataTypesRow[isFixedLengthColumn] = false;
                        break;

                    case ODBC32.SQL_TYPE.CHAR:
                    case ODBC32.SQL_TYPE.WCHAR:
                    case ODBC32.SQL_TYPE.DECIMAL:
                    case ODBC32.SQL_TYPE.NUMERIC:
                    case ODBC32.SQL_TYPE.SMALLINT:
                    case ODBC32.SQL_TYPE.INTEGER:
                    case ODBC32.SQL_TYPE.REAL:
                    case ODBC32.SQL_TYPE.FLOAT:
                    case ODBC32.SQL_TYPE.DOUBLE:
                    case ODBC32.SQL_TYPE.BIT:
                    case ODBC32.SQL_TYPE.TINYINT:
                    case ODBC32.SQL_TYPE.BIGINT:
                    case ODBC32.SQL_TYPE.TYPE_DATE:
                    case ODBC32.SQL_TYPE.TYPE_TIME:
                    case ODBC32.SQL_TYPE.TIMESTAMP:
                    case ODBC32.SQL_TYPE.TYPE_TIMESTAMP:
                    case ODBC32.SQL_TYPE.GUID:
                    case ODBC32.SQL_TYPE.SS_VARIANT:
                    case ODBC32.SQL_TYPE.SS_UTCDATETIME:
                    case ODBC32.SQL_TYPE.SS_TIME_EX:
                    case ODBC32.SQL_TYPE.BINARY:
                        dataTypesRow[isLongColumn]        = false;
                        dataTypesRow[isFixedLengthColumn] = true;
                        break;

                    case ODBC32.SQL_TYPE.SS_UDT:
                    default:
                        // for User defined types don't know if its long or if it is
                        // variable length or not so leave the fields null
                        break;
                    }
                }



                dataTypesRow[columnSizeColumn]       = getTypeInfoValues[indexCOLUMN_SIZE];
                dataTypesRow[createParametersColumn] = getTypeInfoValues[indexCREATE_PARAMS];

                if ((getTypeInfoValues[indexAUTO_UNIQUE_VALUE] == DBNull.Value) ||
                    (Convert.ToInt16(getTypeInfoValues[indexAUTO_UNIQUE_VALUE], null) == 0))
                {
                    dataTypesRow[isAutoIncermentableColumn] = false;
                }
                else
                {
                    dataTypesRow[isAutoIncermentableColumn] = true;
                }

                dataTypesRow[isCaseSensitiveColumn]       = BooleanFromODBC(getTypeInfoValues[indexCASE_SENSITIVE]);
                dataTypesRow[isFixedPrecisionScaleColumn] = BooleanFromODBC(getTypeInfoValues[indexFIXED_PREC_SCALE]);

                if (getTypeInfoValues[indexNULLABLE] != DBNull.Value)
                {
                    //Use Convert.ToInt16 instead of direct cast to short because the value will be Int32 in some cases
                    switch ((ODBC32.SQL_NULLABILITY)Convert.ToInt16(getTypeInfoValues[indexNULLABLE], null))
                    {
                    case ODBC32.SQL_NULLABILITY.NO_NULLS:
                        dataTypesRow[isNullableColumn] = false;
                        break;

                    case ODBC32.SQL_NULLABILITY.NULLABLE:
                        dataTypesRow[isNullableColumn] = true;
                        break;

                    case ODBC32.SQL_NULLABILITY.UNKNOWN:
                        dataTypesRow[isNullableColumn] = DBNull.Value;
                        break;
                    }
                }

                if (DBNull.Value != getTypeInfoValues[indexSEARCHABLE])
                {
                    //Use Convert.ToInt16 instead of direct cast to short because the value will be Int32 in some cases
                    short searchableValue = Convert.ToInt16(getTypeInfoValues[indexSEARCHABLE], null);
                    switch (searchableValue)
                    {
                    case (short)ODBC32.SQL_SEARCHABLE.UNSEARCHABLE:
                        dataTypesRow[isSearchableColumn]         = false;
                        dataTypesRow[isSearchableWithLikeColumn] = false;
                        break;

                    case (short)ODBC32.SQL_SEARCHABLE.LIKE_ONLY:
                        dataTypesRow[isSearchableColumn]         = false;
                        dataTypesRow[isSearchableWithLikeColumn] = true;
                        break;

                    case (short)ODBC32.SQL_SEARCHABLE.ALL_EXCEPT_LIKE:
                        dataTypesRow[isSearchableColumn]         = true;
                        dataTypesRow[isSearchableWithLikeColumn] = false;
                        break;

                    case (short)ODBC32.SQL_SEARCHABLE.SEARCHABLE:
                        dataTypesRow[isSearchableColumn]         = true;
                        dataTypesRow[isSearchableWithLikeColumn] = true;
                        break;
                    }
                }

                dataTypesRow[isUnsignedColumn] = BooleanFromODBC(getTypeInfoValues[indexUNSIGNED_ATTRIBUTE]);

                //For assignment to the DataSet, don't cast the data types -- let the DataSet take care of any conversion
                if (getTypeInfoValues[indexMAXIMUM_SCALE] != DBNull.Value)
                {
                    dataTypesRow[maximumScaleColumn] = getTypeInfoValues[indexMAXIMUM_SCALE];
                }

                if (getTypeInfoValues[indexMINIMUM_SCALE] != DBNull.Value)
                {
                    dataTypesRow[minimumScaleColumn] = getTypeInfoValues[indexMINIMUM_SCALE];
                }

                if (getTypeInfoValues[indexLITERAL_PREFIX] != DBNull.Value)
                {
                    dataTypesRow[literalPrefixColumn] = getTypeInfoValues[indexLITERAL_PREFIX];
                }

                if (getTypeInfoValues[indexLITERAL_SUFFIX] != DBNull.Value)
                {
                    dataTypesRow[literalSuffixColumn] = getTypeInfoValues[indexLITERAL_SUFFIX];
                }

                dataTypesTable.Rows.Add(dataTypesRow);
            }
        }
        private void DataTableFromDataReaderDataTypes(DataTable dataTypesTable, OdbcDataReader dataReader, OdbcConnection connection)
        {
            DataTable schemaTable = null;
            schemaTable = dataReader.GetSchemaTable();
            if (schemaTable == null)
            {
                throw ADP.OdbcNoTypesFromProvider();
            }
            object[] values = new object[schemaTable.Rows.Count];
            DataColumn column19 = dataTypesTable.Columns[DbMetaDataColumnNames.TypeName];
            DataColumn column18 = dataTypesTable.Columns[DbMetaDataColumnNames.ProviderDbType];
            DataColumn column17 = dataTypesTable.Columns[DbMetaDataColumnNames.ColumnSize];
            DataColumn column16 = dataTypesTable.Columns[DbMetaDataColumnNames.CreateParameters];
            DataColumn column15 = dataTypesTable.Columns[DbMetaDataColumnNames.DataType];
            DataColumn column6 = dataTypesTable.Columns[DbMetaDataColumnNames.IsAutoIncrementable];
            DataColumn column14 = dataTypesTable.Columns[DbMetaDataColumnNames.IsCaseSensitive];
            DataColumn column5 = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength];
            DataColumn column13 = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedPrecisionScale];
            DataColumn column4 = dataTypesTable.Columns[DbMetaDataColumnNames.IsLong];
            DataColumn column3 = dataTypesTable.Columns[DbMetaDataColumnNames.IsNullable];
            DataColumn column2 = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchable];
            DataColumn column = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchableWithLike];
            DataColumn column12 = dataTypesTable.Columns[DbMetaDataColumnNames.IsUnsigned];
            DataColumn column11 = dataTypesTable.Columns[DbMetaDataColumnNames.MaximumScale];
            DataColumn column10 = dataTypesTable.Columns[DbMetaDataColumnNames.MinimumScale];
            DataColumn column9 = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralPrefix];
            DataColumn column8 = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralSuffix];
            DataColumn column7 = dataTypesTable.Columns[OdbcMetaDataColumnNames.SQLType];
            while (dataReader.Read())
            {
                TypeMap map;
                dataReader.GetValues(values);
                DataRow row = dataTypesTable.NewRow();
                row[column19] = values[0];
                row[column7] = values[1];
                ODBC32.SQL_TYPE sqltype = (ODBC32.SQL_TYPE) ((short) ((int) Convert.ChangeType(values[1], typeof(int), null)));
                if (!connection.IsV3Driver)
                {
                    if (sqltype == ~ODBC32.SQL_TYPE.WLONGVARCHAR)
                    {
                        sqltype = ODBC32.SQL_TYPE.TYPE_DATE;
                    }
                    else if (sqltype == ~ODBC32.SQL_TYPE.GUID)
                    {
                        sqltype = ODBC32.SQL_TYPE.TYPE_TIME;
                    }
                }
                try
                {
                    map = TypeMap.FromSqlType(sqltype);
                }
                catch (ArgumentException)
                {
                    map = null;
                }
                if (map != null)
                {
                    row[column18] = map._odbcType;
                    row[column15] = map._type.FullName;
                    switch (sqltype)
                    {
                        case ODBC32.SQL_TYPE.SS_TIME_EX:
                        case ODBC32.SQL_TYPE.SS_UTCDATETIME:
                        case ODBC32.SQL_TYPE.SS_VARIANT:
                        case ODBC32.SQL_TYPE.GUID:
                        case ODBC32.SQL_TYPE.WCHAR:
                        case ODBC32.SQL_TYPE.BIT:
                        case ODBC32.SQL_TYPE.TINYINT:
                        case ODBC32.SQL_TYPE.BIGINT:
                        case ODBC32.SQL_TYPE.BINARY:
                        case ODBC32.SQL_TYPE.CHAR:
                        case ODBC32.SQL_TYPE.NUMERIC:
                        case ODBC32.SQL_TYPE.DECIMAL:
                        case ODBC32.SQL_TYPE.INTEGER:
                        case ODBC32.SQL_TYPE.SMALLINT:
                        case ODBC32.SQL_TYPE.FLOAT:
                        case ODBC32.SQL_TYPE.REAL:
                        case ODBC32.SQL_TYPE.DOUBLE:
                        case ODBC32.SQL_TYPE.TIMESTAMP:
                        case ODBC32.SQL_TYPE.TYPE_DATE:
                        case ODBC32.SQL_TYPE.TYPE_TIME:
                        case ODBC32.SQL_TYPE.TYPE_TIMESTAMP:
                            goto Label_02F8;

                        case ODBC32.SQL_TYPE.SS_XML:
                        case ODBC32.SQL_TYPE.WLONGVARCHAR:
                        case ODBC32.SQL_TYPE.LONGVARBINARY:
                        case ODBC32.SQL_TYPE.LONGVARCHAR:
                            goto Label_02BC;

                        case ODBC32.SQL_TYPE.WVARCHAR:
                        case ODBC32.SQL_TYPE.VARBINARY:
                        case ODBC32.SQL_TYPE.VARCHAR:
                            goto Label_02DA;
                    }
                }
                goto Label_0314;
            Label_02BC:
                row[column4] = true;
                row[column5] = false;
                goto Label_0314;
            Label_02DA:
                row[column4] = false;
                row[column5] = false;
                goto Label_0314;
            Label_02F8:
                row[column4] = false;
                row[column5] = true;
            Label_0314:
                row[column17] = values[2];
                row[column16] = values[5];
                if ((values[11] == DBNull.Value) || (Convert.ToInt16(values[11], null) == 0))
                {
                    row[column6] = false;
                }
                else
                {
                    row[column6] = true;
                }
                row[column14] = this.BooleanFromODBC(values[7]);
                row[column13] = this.BooleanFromODBC(values[10]);
                if (values[6] != DBNull.Value)
                {
                    switch (((ODBC32.SQL_NULLABILITY) ((ushort) Convert.ToInt16(values[6], null))))
                    {
                        case ODBC32.SQL_NULLABILITY.NO_NULLS:
                            row[column3] = false;
                            break;

                        case ODBC32.SQL_NULLABILITY.NULLABLE:
                            row[column3] = true;
                            break;

                        case ODBC32.SQL_NULLABILITY.UNKNOWN:
                            row[column3] = DBNull.Value;
                            break;
                    }
                }
                if (DBNull.Value != values[8])
                {
                    switch (Convert.ToInt16(values[8], null))
                    {
                        case 0:
                            row[column2] = false;
                            row[column] = false;
                            break;

                        case 1:
                            row[column2] = false;
                            row[column] = true;
                            break;

                        case 2:
                            row[column2] = true;
                            row[column] = false;
                            break;

                        case 3:
                            row[column2] = true;
                            row[column] = true;
                            break;
                    }
                }
                row[column12] = this.BooleanFromODBC(values[9]);
                if (values[14] != DBNull.Value)
                {
                    row[column11] = values[14];
                }
                if (values[13] != DBNull.Value)
                {
                    row[column10] = values[13];
                }
                if (values[3] != DBNull.Value)
                {
                    row[column9] = values[3];
                }
                if (values[4] != DBNull.Value)
                {
                    row[column8] = values[4];
                }
                dataTypesTable.Rows.Add(row);
            }
        }
コード例 #6
0
ファイル: OdbcCommand.cs プロジェクト: yuyixiaoxiang/runtime
        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);
        }
コード例 #7
0
    public DataSet ConvertDataReaderToDataSet(System.Data.Odbc.OdbcDataReader reader)
    {
        DataSet dataSet = new DataSet();

        do
        {
            // Create data table in runtime
            DataTable schemaTable = reader.GetSchemaTable();
            DataTable dataTable   = new DataTable();

            if (schemaTable != null)
            {
                DataColumn column1 = new DataColumn("id", typeof(int));
                dataTable.Columns.Add(column1);
                DataColumn column2 = new DataColumn("dato", typeof(DateTime));
                dataTable.Columns.Add(column2);
                DataColumn column3 = new DataColumn("editor", typeof(string));
                dataTable.Columns.Add(column3);
                DataColumn column4 = new DataColumn("origin", typeof(int));
                dataTable.Columns.Add(column4);
                DataColumn column5 = new DataColumn("medarbejderid", typeof(string));
                dataTable.Columns.Add(column5);
                DataColumn column6 = new DataColumn("jobid", typeof(int));
                dataTable.Columns.Add(column6);
                DataColumn column7 = new DataColumn("aktnavn", typeof(string));
                dataTable.Columns.Add(column7);
                DataColumn column8 = new DataColumn("timer", typeof(double));
                dataTable.Columns.Add(column8);
                DataColumn column9 = new DataColumn("tdato", typeof(DateTime));
                dataTable.Columns.Add(column9);
                DataColumn column10 = new DataColumn("lto", typeof(string));
                dataTable.Columns.Add(column10);
                DataColumn column11 = new DataColumn("timerkom", typeof(string));
                dataTable.Columns.Add(column11);

                dataSet.Tables.Add(dataTable);

                // Fill the data table from reader data
                while (reader.Read())
                {
                    DataRow dataRow = dataTable.NewRow();

                    dataRow["id"]            = reader.GetValue(0);
                    dataRow["dato"]          = reader.GetValue(1);
                    dataRow["editor"]        = reader.GetValue(2);
                    dataRow["origin"]        = reader.GetValue(3);
                    dataRow["medarbejderid"] = reader.GetValue(4);
                    dataRow["jobid"]         = reader.GetValue(5);
                    dataRow["aktnavn"]       = reader.GetValue(6);
                    dataRow["timer"]         = reader.GetValue(7);
                    dataRow["tdato"]         = reader.GetValue(8);
                    dataRow["lto"]           = reader.GetValue(9);  //10 Overfort omited here
                    dataRow["timerkom"]      = reader.GetValue(10); //11

                    dataTable.Rows.Add(dataRow);
                }
            }
            else
            {
                // No records were returned
                DataColumn column = new DataColumn("RowsAffected");
                dataTable.Columns.Add(column);
                dataSet.Tables.Add(dataTable);
                DataRow dataRow = dataTable.NewRow();
                dataRow[0] = reader.RecordsAffected;
                dataTable.Rows.Add(dataRow);
            }
        }while (reader.NextResult());

        return(dataSet);
    }
コード例 #8
0
        private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior,
                                                   string method,
                                                   bool needReader,
                                                   object[] methodArguments,
                                                   ODBC32.SQL_API odbcApiMethod) { // MDAC 68324

            OdbcDataReader localReader = null;
            try {
                DisposeDeadDataReader();    // this is a no-op if cmdState is not Fetching
                ValidateConnectionAndTransaction(method);  // cmdState will change to Executing

                if(0 != (CommandBehavior.SingleRow & behavior)) {
                    // CommandBehavior.SingleRow implies CommandBehavior.SingleResult
                    behavior |= CommandBehavior.SingleResult;
                }

                ODBC32.RetCode retcode;

                OdbcStatementHandle stmt = GetStatementHandle().StatementHandle;
                _cmdWrapper.Canceling = false;

                if(null != weakDataReaderReference) {
                    if(weakDataReaderReference.IsAlive) {
                        object target = weakDataReaderReference.Target;
                        if(null != target && weakDataReaderReference.IsAlive) {
                            if(!((OdbcDataReader)target).IsClosed) {
                                throw ADP.OpenReaderExists(); // MDAC 66411
                            }
                        }
                    }
                }
                localReader = new OdbcDataReader(this, _cmdWrapper, behavior);

                //Set command properties
                //Not all drivers support timeout. So fail silently if error
                if(!Connection.ProviderInfo.NoQueryTimeout) {
                    TrySetStatementAttribute(stmt,
                        ODBC32.SQL_ATTR.QUERY_TIMEOUT,
                        (IntPtr)this.CommandTimeout);
                }

                // todo: If we remember the state we can omit a lot of SQLSetStmtAttrW calls ...
                // if we do not create a reader we do not even need to do that
                if(needReader) {
                    if(Connection.IsV3Driver) {
                        if(!Connection.ProviderInfo.NoSqlSoptSSNoBrowseTable && !Connection.ProviderInfo.NoSqlSoptSSHiddenColumns) {
                            // Need to get the metadata information

                            //SQLServer actually requires browse info turned on ahead of time...
                            //Note: We ignore any failures, since this is SQLServer specific
                            //We won't specialcase for SQL Server but at least for non-V3 drivers
                            if(localReader.IsBehavior(CommandBehavior.KeyInfo)) {
                                if(!_cmdWrapper._ssKeyInfoModeOn) {
                                    TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.NOBROWSETABLE, (IntPtr)ODBC32.SQL_NB.ON);
                                    TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.HIDDEN_COLUMNS, (IntPtr)ODBC32.SQL_HC.ON);
                                    _cmdWrapper._ssKeyInfoModeOff = false;
                                    _cmdWrapper._ssKeyInfoModeOn = true;
                                }
                            }
                            else {
                                if(!_cmdWrapper._ssKeyInfoModeOff) {
                                    TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.NOBROWSETABLE, (IntPtr)ODBC32.SQL_NB.OFF);
                                    TrySetStatementAttribute(stmt, (ODBC32.SQL_ATTR)ODBC32.SQL_SOPT_SS.HIDDEN_COLUMNS, (IntPtr)ODBC32.SQL_HC.OFF);
                                    _cmdWrapper._ssKeyInfoModeOff = true;
                                    _cmdWrapper._ssKeyInfoModeOn = false;
                                }
                            }
                        }
                    }
                }

                if(localReader.IsBehavior(CommandBehavior.KeyInfo) ||
                    localReader.IsBehavior(CommandBehavior.SchemaOnly)) {

                    retcode = stmt.Prepare(CommandText);

                    if(ODBC32.RetCode.SUCCESS != retcode) {
                        _connection.HandleError(stmt, retcode);
                    }
                }

                bool mustRelease = false;
                CNativeBuffer parameterBuffer = _cmdWrapper._nativeParameterBuffer;

                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    //Handle Parameters
                    //Note: We use the internal variable as to not instante a new object collection,
                    //for the the common case of using no parameters.
                    if((null != _parameterCollection) && (0 < _parameterCollection.Count)) {
                        int parameterBufferSize = _parameterCollection.CalcParameterBufferSize(this);

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

                        parameterBuffer.DangerousAddRef(ref mustRelease);

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

                    if(!localReader.IsBehavior(CommandBehavior.SchemaOnly)) {

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

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

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

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

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

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

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

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

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

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

                this.weakDataReaderReference = new WeakReference(localReader);

                // XXXCommand.Execute should position reader on first row returning result
                // any exceptions in the initial non-row returning results should be thrown
                // from from ExecuteXXX not the DataReader
                if(!localReader.IsBehavior(CommandBehavior.SchemaOnly)) {
                    localReader.FirstResult();
                }
                cmdState = ConnectionState.Fetching;
            }
            finally {
                if(ConnectionState.Fetching != cmdState) {
                    if(null != localReader) {
                        // clear bindings so we don't grab output parameters on a failed execute
                        if(null != _parameterCollection) {
                            _parameterCollection.ClearBindings();
                        }
                        ((IDisposable)localReader).Dispose();
                    }
                    if(ConnectionState.Closed != cmdState) {
                        cmdState = ConnectionState.Closed;
                    }
                }
            }
            return localReader;
        }
コード例 #9
0
        private void DataTableFromDataReaderDataTypes(DataTable dataTypesTable, OdbcDataReader dataReader, OdbcConnection connection)
        {
            DataTable schemaTable = null;

            schemaTable = dataReader.GetSchemaTable();
            if (schemaTable == null)
            {
                throw ADP.OdbcNoTypesFromProvider();
            }
            object[]   values   = new object[schemaTable.Rows.Count];
            DataColumn column19 = dataTypesTable.Columns[DbMetaDataColumnNames.TypeName];
            DataColumn column18 = dataTypesTable.Columns[DbMetaDataColumnNames.ProviderDbType];
            DataColumn column17 = dataTypesTable.Columns[DbMetaDataColumnNames.ColumnSize];
            DataColumn column16 = dataTypesTable.Columns[DbMetaDataColumnNames.CreateParameters];
            DataColumn column15 = dataTypesTable.Columns[DbMetaDataColumnNames.DataType];
            DataColumn column6  = dataTypesTable.Columns[DbMetaDataColumnNames.IsAutoIncrementable];
            DataColumn column14 = dataTypesTable.Columns[DbMetaDataColumnNames.IsCaseSensitive];
            DataColumn column5  = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength];
            DataColumn column13 = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedPrecisionScale];
            DataColumn column4  = dataTypesTable.Columns[DbMetaDataColumnNames.IsLong];
            DataColumn column3  = dataTypesTable.Columns[DbMetaDataColumnNames.IsNullable];
            DataColumn column2  = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchable];
            DataColumn column   = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchableWithLike];
            DataColumn column12 = dataTypesTable.Columns[DbMetaDataColumnNames.IsUnsigned];
            DataColumn column11 = dataTypesTable.Columns[DbMetaDataColumnNames.MaximumScale];
            DataColumn column10 = dataTypesTable.Columns[DbMetaDataColumnNames.MinimumScale];
            DataColumn column9  = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralPrefix];
            DataColumn column8  = dataTypesTable.Columns[DbMetaDataColumnNames.LiteralSuffix];
            DataColumn column7  = dataTypesTable.Columns[OdbcMetaDataColumnNames.SQLType];

            while (dataReader.Read())
            {
                TypeMap map;
                dataReader.GetValues(values);
                DataRow row = dataTypesTable.NewRow();
                row[column19] = values[0];
                row[column7]  = values[1];
                ODBC32.SQL_TYPE sqltype = (ODBC32.SQL_TYPE)((short)((int)Convert.ChangeType(values[1], typeof(int), null)));
                if (!connection.IsV3Driver)
                {
                    if (sqltype == ~ODBC32.SQL_TYPE.WLONGVARCHAR)
                    {
                        sqltype = ODBC32.SQL_TYPE.TYPE_DATE;
                    }
                    else if (sqltype == ~ODBC32.SQL_TYPE.GUID)
                    {
                        sqltype = ODBC32.SQL_TYPE.TYPE_TIME;
                    }
                }
                try
                {
                    map = TypeMap.FromSqlType(sqltype);
                }
                catch (ArgumentException)
                {
                    map = null;
                }
                if (map != null)
                {
                    row[column18] = map._odbcType;
                    row[column15] = map._type.FullName;
                    switch (sqltype)
                    {
                    case ODBC32.SQL_TYPE.SS_TIME_EX:
                    case ODBC32.SQL_TYPE.SS_UTCDATETIME:
                    case ODBC32.SQL_TYPE.SS_VARIANT:
                    case ODBC32.SQL_TYPE.GUID:
                    case ODBC32.SQL_TYPE.WCHAR:
                    case ODBC32.SQL_TYPE.BIT:
                    case ODBC32.SQL_TYPE.TINYINT:
                    case ODBC32.SQL_TYPE.BIGINT:
                    case ODBC32.SQL_TYPE.BINARY:
                    case ODBC32.SQL_TYPE.CHAR:
                    case ODBC32.SQL_TYPE.NUMERIC:
                    case ODBC32.SQL_TYPE.DECIMAL:
                    case ODBC32.SQL_TYPE.INTEGER:
                    case ODBC32.SQL_TYPE.SMALLINT:
                    case ODBC32.SQL_TYPE.FLOAT:
                    case ODBC32.SQL_TYPE.REAL:
                    case ODBC32.SQL_TYPE.DOUBLE:
                    case ODBC32.SQL_TYPE.TIMESTAMP:
                    case ODBC32.SQL_TYPE.TYPE_DATE:
                    case ODBC32.SQL_TYPE.TYPE_TIME:
                    case ODBC32.SQL_TYPE.TYPE_TIMESTAMP:
                        goto Label_02F8;

                    case ODBC32.SQL_TYPE.SS_XML:
                    case ODBC32.SQL_TYPE.WLONGVARCHAR:
                    case ODBC32.SQL_TYPE.LONGVARBINARY:
                    case ODBC32.SQL_TYPE.LONGVARCHAR:
                        goto Label_02BC;

                    case ODBC32.SQL_TYPE.WVARCHAR:
                    case ODBC32.SQL_TYPE.VARBINARY:
                    case ODBC32.SQL_TYPE.VARCHAR:
                        goto Label_02DA;
                    }
                }
                goto Label_0314;
Label_02BC:
                row[column4] = true;
                row[column5] = false;
                goto Label_0314;
Label_02DA:
                row[column4] = false;
                row[column5] = false;
                goto Label_0314;
Label_02F8:
                row[column4] = false;
                row[column5] = true;
Label_0314:
                row[column17] = values[2];
                row[column16] = values[5];
                if ((values[11] == DBNull.Value) || (Convert.ToInt16(values[11], null) == 0))
                {
                    row[column6] = false;
                }
                else
                {
                    row[column6] = true;
                }
                row[column14] = this.BooleanFromODBC(values[7]);
                row[column13] = this.BooleanFromODBC(values[10]);
                if (values[6] != DBNull.Value)
                {
                    switch (((ODBC32.SQL_NULLABILITY)((ushort)Convert.ToInt16(values[6], null))))
                    {
                    case ODBC32.SQL_NULLABILITY.NO_NULLS:
                        row[column3] = false;
                        break;

                    case ODBC32.SQL_NULLABILITY.NULLABLE:
                        row[column3] = true;
                        break;

                    case ODBC32.SQL_NULLABILITY.UNKNOWN:
                        row[column3] = DBNull.Value;
                        break;
                    }
                }
                if (DBNull.Value != values[8])
                {
                    switch (Convert.ToInt16(values[8], null))
                    {
                    case 0:
                        row[column2] = false;
                        row[column]  = false;
                        break;

                    case 1:
                        row[column2] = false;
                        row[column]  = true;
                        break;

                    case 2:
                        row[column2] = true;
                        row[column]  = false;
                        break;

                    case 3:
                        row[column2] = true;
                        row[column]  = true;
                        break;
                    }
                }
                row[column12] = this.BooleanFromODBC(values[9]);
                if (values[14] != DBNull.Value)
                {
                    row[column11] = values[14];
                }
                if (values[13] != DBNull.Value)
                {
                    row[column10] = values[13];
                }
                if (values[3] != DBNull.Value)
                {
                    row[column9] = values[3];
                }
                if (values[4] != DBNull.Value)
                {
                    row[column8] = values[4];
                }
                dataTypesTable.Rows.Add(row);
            }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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;
        }