MS Access, именованные параметры и имена столбцов - PullRequest
1 голос
/ 01 февраля 2011

У меня есть следующий запрос, который я выполняю в базе данных Access.Запрос при запуске в Access возвращает точные результаты.Однако при запуске из кода я получаю обратно все элементы в базе данных, даже те, которые выходят за пределы диапазона дат, который я ищу.

Мне было интересно, если проблема была в том, что имена параметров совпадаюткак имена столбцов в таблице, поэтому я изменил имена параметров @StartDate и @EndDate на @FromDate и @ToDate, и это устранило проблему, если имена параметров отличаются, я получаю правильный набор результатов обратно.Это касается меня, потому что в проекте, над которым я работаю, этот шаблон дублируется повсюду.Однако я использую параметр с именем @Id для обновления записей на Id (имя столбца в таблице базы данных), и это работает нормально.Это странный крайний случай?Может кто-нибудь пролить свет на это поведение.

Извините за массивный пример кода, но в этом случае я думаю, что нужен весь метод.

  public override AcademicCycleTransportCollection FetchForDateRange(DateTime startDate, DateTime endDate) {
     const String query =
        "PARAMETERS \n" +
        "   @StartDate DATE, \n" +
        "   @EndDate DATE \n" +
        "   ; \n" +
        "SELECT \n" +
        "      [AcademicCycle].[Id] AS [Id], \n "  +
        "      [AcademicCycle].[Name] AS [Name], \n "  +
        "      [AcademicCycle].[AcademicCycleCategoryId] AS [AcademicCycleCategoryId], \n "  +
        "      [AcademicCycle].[ParentAcademicCycleId] AS [ParentAcademicCycleId], \n "  +
        "      [AcademicCycle].[StartDate] AS [StartDate], \n "  +
        "      [AcademicCycle].[EndDate] AS [EndDate], \n "  +
        "      [AcademicCycle].[IsPerpetual] AS [IsPerpetual], \n "  +
        "      [AcademicCycle].[IsLocked] AS [IsLocked] \n " +
        "FROM \n" +
        "  AcademicCycle \n" +
        "WHERE \n" +
        "  (StartDate <= @EndDate AND EndDate >= @StartDate) OR \n" +
        "  IsPerpetual <> 0";

     AcademicCycleTransportCollection transportCollection = new AcademicCycleTransportCollection();

     OleDbCommand _fetchForDateRangeCommand = null;

     if (_fetchForDateRangeCommand == null) {
        OleDbConnection connection = _parentDataConnection.Connection;
        _fetchForDateRangeCommand = new OleDbCommand(query, connection);
        _fetchForDateRangeCommand.Parameters.Add("@StartDate", OleDbType.Date);
        _fetchForDateRangeCommand.Parameters.Add("@EndDate", OleDbType.Date);
     }

     _fetchForDateRangeCommand.Transaction = _parentDataConnection.Transaction;

     _fetchForDateRangeCommand.Parameters["@StartDate"].Value = startDate;
     _fetchForDateRangeCommand.Parameters["@EndDate"].Value = endDate;

     using (OleDbDataReader dbReader = _fetchForDateRangeCommand.ExecuteReader()) {
        NullableDataReader reader = new NullableDataReader(dbReader);

        while (reader.Read()) {
           AcademicCycleTransport transport = FillTransport(reader);
           transportCollection.Add(transport);
        }
        if (!reader.IsClosed) {
           reader.Close();
        }
     }

     return transportCollection;
  }

Ответы [ 2 ]

2 голосов
/ 28 декабря 2013

Как вы это сделали, OleDb использует позиционную вставку параметров, поэтому ваш первый параметр в SQL, @EndDate, заменяется первым переданным параметром, @StartDate.Имена параметров полностью игнорируются при использовании позиционной вставки.

Однако малоизвестный факт, что OleDb действительно принимает именованные параметры.Вы просто должны объявить параметры и в SQL.

См .: low-bandwidth.blogspot.com.au / 2013/12 / positional-msaccess-oledb-parameters.html

Если вы НЕ объявляете параметры в SQL, OleDb использует чисто позиционную вставку параметров, и не имеет значения, соответствуют ли имена параметров SQL или параметры используются дважды в SQL- он будет просто проходить и слепо заменять любые найденные параметры в SQL по порядку от начала до конца с переданными.

Однако, если вы действительно объявите параметры правильно, вы получите преимущество от именованных параметров и параметров.разрешено повторяться несколько раз в инструкции SQL.

0 голосов
/ 01 февраля 2011

попробуйте отредактировать строку запроса напрямую с нужными параметрами.Простой пример (выходная строка запроса):

"ВЫБЕРИТЕ t001_clients.cli_id как id, t001_clients.cli_name WHERE (id = 1);"

Не самый лучший способ, но сработает.Будьте внимательны с символами типа в параметрах ("cli_name = 'John Smith'" или "cli_birthday = # 12/27/1980 #")

Кроме того, почему вы не использовали запросы linq?Должно быть проще ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...