2011-02-01 15 views
1

私はAccessデータベースで次のクエリを実行しています。 Accessで実行されたクエリは、正確な結果を返します。しかし、コードから実行すると、データベース内のすべての項目が返されます。たとえ日付範囲外の項目であっても、検索しています。MSアクセス、名前付きパラメータと列名

パラメータ名場合は、パラメータ名は、テーブルの列名と同じであるので、私は@FromDate@ToDateするパラメータ名@StartDate@EndDateを変更して、この問題を修正するので、問題だった場合、私は思っていました私は正しい結果を得ることができます。これは、私がこのパターンに取り組んでいるプロジェクトでは、全面的に複製されているからです。しかし、Id(dbテーブルの列名)でレコードを更新するのに@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; 
    } 

答えて

1

OleDbは、位置パラメータの挿入を使用しているため、SQLの最初のパラメータ '@EndDate'は、渡された最初のパラメータ '@StartDate'で置換されます。位置指定挿入を使用する場合、パラメーターの名前は完全に無視されます。

しかし、OleDbが名前付きパラメータを実際に受け入れることは、ほとんど知られていません。 SQLでパラメータを宣言しなければなりません。

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

あなたはSQLでパラメータを宣言しない場合、OLEDBは純粋に位置パラメータ挿入を使用し、パラメータの名前は、SQLと一致した場合、またはパラメータが使用されている場合、それは問題ではありません。 SQLの中で2回 - これは、最初から最後までSQLで見つかったパラメータを盲目的に置き換えるだけです。

ただし、パラメータを正しく宣言すると、名前付きパラメータとパラメータをSQL文内で複数回繰り返すことができます。

0

クエリ文字列を目的のパラメータで直接編集してみます。簡単な例(出力クエリ文字列):

"SELECT t001_clients.cli_id as id、t001_clients.cli_name WHERE(id = 1);"

最善の方法ではありませんが、動作します。パラメータのタイプ文字( "cli_name = 'John Smith'または" cli_birthday =#12/27/1980# ")に注意してください。

さらに、なぜlinqクエリを使用しませんでしたか?

+0

これは許容される解決策ではありません。一般的な使いやすさのために名前付きパラメータを使用します。 linqについては... linqにアクセスするには?私はサードパーティのソリューションがあると思う、あなたのデータベースに更新と挿入を行うことについて、あなたはlinq経由でそれらを行うことができます... –

関連する問題