Исключение OleDbCommand.ExecuteReader

Мое приложение C# .NET 3.5 выдает необычное исключение при выполнении OleDbCommand.ExecuteReader. Приложение делает 5 аналогичных запросов к базе данных Access 2007. Три запроса выполняются без проблем; другие 2 вызывают точно такое же исключение.

Это запрос, который проходит:

String query =
    "SELECT " +
        "bas.[BAS BACnet Object Type/Instance], " + // OBJECT_IDENTIFIER_ATTRIBUTE/ITEM_REFERENCE_ATTRIBUTE
        "bas.[BAS BACnet Object Name], " +          // USER_NAME_ATTRIBUTE
        "bas.[BAS Point List Description], " +      // DESCRIPTION_ATTRIBUTE
        "bas.[BAS Monitor Only], " +                // MONITOR_ONLY_ATTRIBUTE
        "ref.[ENUM_H], " +                          // PROPERTY_REFERENCE_VALUE_ATTRIBUTE
        "yk.[CCC Max Value (eng units)], " +        // MAX_PRESENT_VALUE_ATTRIBUTE
        "yk.[CCC Min Value (eng units)], " +        // MIN_PRESENT_VALUE_ATTRIBUTE
        "yk.[CCC Enum/Data Set], " +                // UNITS_ATTRIBUTE
        "ore.[ORE COV Increment], " +               // COV_INCREMENT_ATTRIBUTE
        "ore.[ORE Display Precision] " +            // DISPLAY_PRECISION_ATTRIBUTE
    "FROM (([OV2 BAS] AS bas " +
    "INNER JOIN [OV2 ORE] AS ore ON bas.[Ref ID] = ore.[Ref ID]) " +
    "INNER JOIN [OV2 RefID] AS ref ON bas.[Ref ID] = ref.[Ref ID]) " +
    "INNER JOIN [YK CAPP] AS yk ON bas.[Ref ID] = yk.[Ref ID] " +
    "WHERE bas.[BAS BACnet Object Type/Instance] LIKE 'AV%';";

this.RunQuery(query, MappingTable.AV_QUERY_IP_FIELDS, this.IPAnalogValuesList);

Это запрос, который выдает исключение:

String query =
    "SELECT " +
        "bas.[BAS BACnet Object Type/Instance], " + // OBJECT_IDENTIFIER_ATTRIBUTE/ITEM_REFERENCE_ATTRIBUTE
        "bas.[BAS BACnet Object Name], " +          // USER_NAME_ATTRIBUTE
        "bas.[BAS Point List Description], " +      // DESCRIPTION_ATTRIBUTE
        "bas.[BAS Monitor Only], " +                // MONITOR_ONLY_ATTRIBUTE
        "ref.[ENUM_H], " +                          // PROPERTY_REFERENCE_VALUE_ATTRIBUTE
        "ses.[ENUM_H], " +                          // STATES_TEXT_ATTRIBUTE
        "ore.[ORE States] " +                       // ACTIVE_TEXT_ATTRIBUTE/INACTIVE_TEXT_ATTRIBUTE
    "FROM (([OV2 BAS] AS bas " +
    "INNER JOIN [OV2 RefID] AS ref ON bas.[Ref ID] = ref.[Ref ID]) " +
    "INNER JOIN [OV2 ORE] AS ore ON bas.[Ref ID] = ore.[Ref ID]) " +
    "INNER JOIN [StatesEnumSet] AS ses ON ore.[ORE States] = ses.[ID] " +
    "WHERE bas.[BAS BACnet Object Type/Instance] LIKE 'BV%';";

this.RunQuery(query, MappingTable.BV_QUERY_FIELDS, this.BinaryValuesList);

Вот как выполняются все запросы:

private void RunQuery(String query, Int32 fieldCount, Object target)
{
    OleDbCommand cmd = null;
    OleDbDataReader reader = null;

    try
    {
        OleDbConnectionStringBuilder connection = new OleDbConnectionStringBuilder();
        connection.Provider = "Microsoft.ACE.OLEDB.12.0";
        connection.DataSource = XML_Generator.Program.MappingTableFilename;
        connection.PersistSecurityInfo = false;

        this.DbConnection = new OleDbConnection(connection.ToString());
        this.DbConnection.Open();

        using (cmd = new OleDbCommand(query, this.DbConnection))
        {
            cmd.Connection = this.DbConnection;
            cmd.CommandText = query;
            cmd.CommandType = System.Data.CommandType.Text;
            reader = cmd.ExecuteReader(); // <== Exception is thrown here.

            while (reader.Read())
            {
                . . .
            }
        }

        if (this.DbConnection != null)
        {
            this.DbConnection.Close();
            this.DbConnection = null;
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

Это исключение:

System.Data.OleDb.OleDbException: для одного или нескольких обязательных параметров не задано значение. в System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr) в System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARA MS dbParams, Object& executeResult) в System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult) в System. Data.OleDb.OleDbCommand.ExecuteCommand(поведение CommandBehavior, объект и executeResult) в System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(поведение CommandBehavior, метод String) в System.Data.OleDb.OleDbCommand.ExecuteReader(поведение CommandBehavior) в System. Data.OleDb.OleDbCommand.ExecuteReader() в XML_Generator.MappingTable.RunQuery (строковый запрос, Int32 fieldCount, Object target) в C:\ccmdb\prep\ov2_shared_cec_v1.0\ov2_shared_cec\Private\Tools\XML_G enerator\XML_Generator\MappingTable. КС: строка 312

Любая помощь приветствуется. Спасибо.


person Jim Fell    schedule 05.01.2012    source источник
comment
вопрос .. где вы объявляете объект читателя ..?   -  person MethodMan    schedule 05.01.2012
comment
@DJKRAZE: это объявлено локально в функции. Я обновил ОП, чтобы уточнить.   -  person Jim Fell    schedule 05.01.2012
comment
хорошо, я этого не видел.. хорошо, позвольте мне еще раз взглянуть на ваш код, есть лучший способ создать OleDbCommand и объекты соединения, дайте мне секунду, также можете ли вы опубликовать полную строку соединения.. как она объявлена ​​в ваш код трудно сказать, может быть там проблема или нет ... вы вообще используете файл .config? Я бы рекомендовал разместить строку подключения в файле конфигурации   -  person MethodMan    schedule 05.01.2012


Ответы (3)


вот пример того, что объект OleDbConnection, Command и DataReader может быть объявлен пример того, как должна выглядеть строка подключения, если вы решите сделать это статической переменной

<add key="strAccessConnectionString" value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\castonmr\Documents\"Your AccessDB Name.mdb";Mode='Share Exclusive';Jet OLEDB:Database Password="your password";"/>    


try
{
    OleDbConnection oleconn = null;
    OleDbDataReader reader = null;
    oleconn = new OleDbConnection(strAccessConnectionString);
    oleconn.Open();
    using (OleDbCommand cmd = new OleDbCommand())
    {
       cmd.Connection = oleconn;
       cmd.CommandText = query;
       cmd.CommandType = CommandType.Text;
       reader = cmd.ExecuteReader();
    }
}//try
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}
person MethodMan    schedule 05.01.2012
comment
Должен ли я закрыть базу данных после завершения оператора using? - person Jim Fell; 05.01.2012
comment
зависит от того, что вы хотите сделать.. использование будет удалять базовое соединение и возвращать его в пул соединений.. это зависит от того, что вам действительно нужно делать.. повторное открытие и закрытие соединений может быть дорогостоящим в отношении раунда поездки - person MethodMan; 05.01.2012
comment
Спасибо. Должен ли reader.Read() быть внутри блока using? - person Jim Fell; 05.01.2012
comment
Из вашего примера видно, что для cmd.Connection установлено значение null. Это правильно? Должен ли он быть установлен на oleconnStkLink? - person Jim Fell; 05.01.2012
comment
не обязательно, но если вы планируете выполнять какое-либо чтение из этого в цикле while, почему бы просто не сохранить его в рамках использования.. это не повредит, поскольку нулевое назначение читателя было объявлено вне использования(), это делает его по-прежнему доступным Я обычно делаю свое кодирование в рамках использования - person MethodMan; 05.01.2012
comment
@ Джим, ему все еще нужно обновить свой код, чтобы он указывал на действительный oleConn. Я полагаю, что я заявил, что в той части, где мне было предложено добавить строку подключения в файл .config - person MethodMan; 05.01.2012
comment
Если бы oleConn был недействительным, разве все 5 запросов не завершились бы ошибкой? - person Jim Fell; 05.01.2012

Кто-то переименовал одно из полей в базе данных. -_-

person Jim Fell    schedule 09.01.2012

эта ошибка может быть связана с тем, что в вашем mdb нет всех столбцов/объектов, необходимых для выполнения запроса, вы можете дважды проверить файл mdb и посмотреть, правильно ли выполняется запрос

person Brijesh Mishra    schedule 05.01.2012
comment
Я дважды проверил базу данных. Все это началось, когда я обновил запросы, чтобы отразить изменение в базе данных (в одну из таблиц был добавлен новый столбец). На это новое поле (только для монитора BAS) ссылаются одинаково во всех запросах. - person Jim Fell; 05.01.2012
comment
возможно, сделайте несколько проб и ошибок, измените запрос об ошибке, чтобы выбрать bas.*, * для анализа возврата столбца, - person Brijesh Mishra; 05.01.2012