ExecuteScalar всегда возвращает 0

Я не уверен, почему это происходит. Я видел ту же проблему в Интернете с небольшой помощью, чтобы исправить ее.

Когда я запускаю свой запрос в Access, я получаю разные значения в диапазоне от 0 до 10, но по какой-то причине он не возвращает это же значение внутри моего кода.

static int OrdersPerHour(string User)
    {
        int? OrdersPerHour = 0;
        OleDbConnection conn = new OleDbConnection(strAccessConn);
        DateTime curTime = DateTime.Now;


        try
        {

            string query = "SELECT COUNT(ControlNumber) FROM Log WHERE DateChanged > #" + curTime.AddHours(-1) + "# AND User = '" + User + "' AND Log.EndStatus in ('Needs Review', 'Check Search', 'Vision Delivery', 'CA Review', '1TSI To Be Delivered');";
            OleDbCommand dbcommand = new OleDbCommand(query, conn);
            dbcommand.Connection.Open();
            dbcommand.CommandType = CommandType.Text;
            dbcommand.CommandText = query;
            OrdersPerHour = (int?)dbcommand.ExecuteScalar();


                      }
        catch (OleDbException ex)
        {

        }
        finally
        {
            conn.Close();
        }
        return OrdersPerHour.Value;

    }

person MaylorTaylor    schedule 24.05.2013    source источник
comment
Возможно, вы захотите отредактировать, чтобы улучшить форматирование уценки. Также вы имели в виду, что часть этого кода находится внутри try{} ?   -  person Buh Buh    schedule 25.05.2013
comment
Пожалуйста, используйте параметры... Внедрение SQL вполне реально   -  person Marc Gravell    schedule 25.05.2013
comment
1.) Используйте параметризованные запросы. 2.) Почему у вас пустой Try Catch Finally? Это просто для того, чтобы гарантировать, что соединение закрыто? Вы должны иметь OleDbConnection в заявлении using.   -  person Dave Zych    schedule 25.05.2013


Ответы (2)


Не используйте конкатенацию строк и синтаксис Access для создания команд SQL.
Используйте простой параметризованный запрос, подобный этому.

string query = "SELECT COUNT(ControlNumber) FROM Log " + 
                "WHERE DateChanged > ? AND [User] = ? AND " + 
                "Log.EndStatus in ('Needs Review', 'Check Search', 'Vision Delivery'," + 
                "'CA Review', '1TSI To Be Delivered');";

  OleDbCommand dbcommand = new OleDbCommand(query, conn);
  dbcommand.Parameters.AddWithValue("@p1", curTime.AddHours(-1));
  dbcommand.Parameters.AddWithValue("@p2", User);
  dbcommand.Connection.Open();
  dbcommand.CommandType = CommandType.Text;
  OrdersPerHour = (int)dbcommand.ExecuteScalar();

Таким образом, бремя правильной интерпретации вашего значения передается коду Framework, который может форматировать даты, десятичные числа и строки в соответствии с требованиями вашей базы данных. Кстати, это также предотвратит Sql Injection

Кроме того, слово USER является зарезервированным ключевым словом в Access SQL, поэтому вам необходимо заключить его в квадратные скобки.

person Steve    schedule 24.05.2013
comment
В C# вы можете использовать символ @, чтобы запрос занимал несколько строк без необходимости конкатенации. - person PeteGO; 25.05.2013
comment
Хотя вы правы в использовании символа @, вы также должны упомянуть тот факт, что это использование добавляет значительное количество пробелов в построенную строку (в зависимости от того, как вы форматируете строки). Попробуйте напечатать длину этой строки против той же с символом @. Кроме того, конкатенация строк постоянного текста, подобного этому, разрешается во время компиляции, создавая статически определенную уникальную строку без дорогостоящих конкатов строк (просмотр кода IL подтверждает это) - person Steve; 25.05.2013
comment
Я не получаю несоответствие типа данных в выражении критериев. ошибка после запуска моего ExecuteScalar() - person MaylorTaylor; 28.05.2013
comment
Проверьте, действительно ли столбец DateChanged является столбцом DateTime, столбец User является текстовым типом данных. - person Steve; 28.05.2013

Первое и самое важное: используйте параметризованные запросы!

Что касается вашей проблемы, я предлагаю вам отладить код:

Получите Commandtext вашей «OleDbCommand dbcommand» и вручную запросите, чтобы увидеть, получите ли вы тот же результат.

Кроме того, вы должны поместить свой код в блок try catch, иначе он вообще не имеет смысла.

person Fabian Bigler    schedule 24.05.2013