Results 1 to 7 of 7

Thread: OleDbCommand Query Using Parameters Not Quite Working

  1. #1

    Thread Starter
    Member
    Join Date
    Jun 2007
    Posts
    41

    OleDbCommand Query Using Parameters Not Quite Working

    Hello,

    Running VB.net and using an Access MDB as the backend database. Connection string for database is:
    Code:
    OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0 ;Data Source=db.mdb")
    I'm trying to do a select query to get all of the results where StartTime is between two dates. StartTime is a column in the Access DB of type Datetime. It contains both the date and time information, so I'm attempting to use the SQL command DateValue to strip off the time. However, this isn't working when I use parameters with the query.

    For example, this doesn't return any results:
    Code:
            Dim query As String = "SELECT * FROM Shifts WHERE DateValue(StartTime) >= @startperiod AND DateValue(StartTime) <= @endperiod;"
    
            Dim pStart As New DateTime(2023, 3, 1)
            Dim pEnd As New DateTime(2023, 3, 15)
    
            Dim cmd As OleDbCommand = New OleDbCommand(query, cn)
    
            cmd.Parameters.AddWithValue("@startperiod", pStart)
            cmd.Parameters.AddWithValue("@endperiod", pEnd)
    
            'run cmd.ExecuteReader, and go through the results, etc
    However, if I change the query string to the value of pEnd (without using a parameter), then this successfully returns the results I am looking for:

    Code:
            Dim query As String = "SELECT * FROM Shifts WHERE DateValue(StartTime) >= @startperiod AND DateValue(StartTime) <= @endperiod;"
    
            Dim pStart As New DateTime(2023, 3, 1)
            Dim pEnd As New DateTime(2023, 3, 15)
    
            query = query.Replace("@endperiod", "#" & pEnd.ToShortDateString & "#")
    
            Dim cmd As OleDbCommand = New OleDbCommand(query, cn)
    
            cmd.Parameters.AddWithValue("@startperiod", pStart)
    
            'run cmd.ExecuteReader, and go through the results, etc
    Here is a sample of the database table:
    Name:  2023-03-18 12_15_58-Window.png
Views: 49
Size:  5.4 KB

    Any ideas what I am doing wrong with the first option?
    Last edited by contentednova; Mar 18th, 2023 at 02:17 PM.

  2. #2

    Thread Starter
    Member
    Join Date
    Jun 2007
    Posts
    41

    Re: OleDbCommand Query Using Parameters Not Quite Working

    I haven't found the reason for the problem yet, but I found a cleaner way to do what I want to do:

    Code:
    SELECT * FROM Shifts WHERE StartTime BETWEEN @startperiod AND @endperiod
    I never knew about the BETWEEN command, I guess you learn something new everyday. Still curious why the original method I was using failed though.

  3. #3
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,889

    Re: OleDbCommand Query Using Parameters Not Quite Working

    A quick web search shows:
    The DateValue() function returns a date based on a string.
    So what is happening is that the DateTime value is being converted to a String (to be passed to DateValue), and then DateValue converts it back to a Date... which may or may not include a Time component.


    It is important to note that when converting a Date/DateTime to or from a String, there can be conversion issues that mean the value gets misinterpreted. This is most likely to mean that the Month and Day values get swapped around (eg: January 3rd gets interpreted as March 1st), and if that is happening it would explain the original issue.



    For queries against Access based databases, you can actually use a seemingly strange trick to eliminate the Time portion of a Date/DateTime value, which is to use the Int() function, eg:
    Code:
    SELECT * FROM Shifts WHERE Int(StartTime) BETWEEN @startperiod AND @endperiod
    This works because internally Date/DateTime values are stored as numbers (eg: 38549.355), with the integer portion representing the date, and the decimal portion representing the time (0.5 meaning midday).

  4. #4

    Thread Starter
    Member
    Join Date
    Jun 2007
    Posts
    41

    Re: OleDbCommand Query Using Parameters Not Quite Working

    Thank you so much. I didn't realize it was converting it to a string and back to a date. I know different regions format dates differently so I was purposely trying to avoid any string representations.

  5. #5

    Thread Starter
    Member
    Join Date
    Jun 2007
    Posts
    41

    Re: OleDbCommand Query Using Parameters Not Quite Working

    I think I spoke too soon, this returns nothing:

    Code:
            Dim query As String = "SELECT * FROM Shifts WHERE Int(StartTime) BETWEEN @startperiod AND @endperiod;"
    
            Dim pStart As New DateTime(2023, 3, 1)
            Dim pEnd As New DateTime(2023, 3, 15)
    
            Dim cmd As OleDbCommand = New OleDbCommand(query, cn)
    
            cmd.Parameters.AddWithValue("@startperiod", pStart)
            cmd.Parameters.AddWithValue("@endperiod", pEnd))
    But if I hardcode the dates, it works:

    Code:
            Dim query As String = "SELECT * FROM Shifts WHERE Int(StartTime) BETWEEN #03/01/2023# AND #03/15/2023#;"
    
            Dim cmd As OleDbCommand = New OleDbCommand(query, cn)
    Could the VB.net datetime type possibly not be compatible with the access Int() function?

  6. #6
    PowerPoster ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    2,952

    Re: OleDbCommand Query Using Parameters Not Quite Working

    try and adapt this sample to your needs

    Code:
     Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim sDB As String = "E:\Adressen.mdb"
            Dim sCon As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
                                    "Data Source=" & sDB & ";"
    
            Dim Cn As OleDb.OleDbConnection = New OleDb.OleDbConnection(sCon)
            Dim dt As New DataTable
            Dim err As String = Nothing
    
        
    
             Dim pStart As New DateTime(2020, 1, 29)
            Dim pEnd As New DateTime(2020, 10, 29)
    
    
            Using Cn
                Using cmd As New OleDbCommand With {.Connection = Cn}
                    cmd.CommandText = "SELECT * FROM tbl_Tanken WHERE TankDatum >= @nDatumStart AND TankDatum < @nDatumEnde"
                    cmd.Parameters.AddWithValue("@nDatumStart", OleDbType.Date).Value = pStart.Date
                    cmd.Parameters.AddWithValue("@nDatumEnde", OleDbType.Date).Value = pEnd.Date.AddDays(1)
            Try
                Cn.Open()
                dt.Load(cmd.ExecuteReader)
            Catch ex As Exception
                err = ex.Message
            End Try
                End Using
            End Using
            DataGridView1.DataSource = dt
    
        End Sub
    Last edited by ChrisE; Mar 19th, 2023 at 02:20 AM.
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  7. #7
    PowerPoster
    Join Date
    Jun 2013
    Posts
    6,428

    Re: OleDbCommand Query Using Parameters Not Quite Working

    Quote Originally Posted by contentednova View Post
    I think I spoke too soon, this returns nothing:

    Code:
            Dim query As String = "SELECT * FROM Shifts WHERE Int(StartTime) BETWEEN @startperiod AND @endperiod;"
    
            Dim pStart As New DateTime(2023, 3, 1)
            Dim pEnd As New DateTime(2023, 3, 15)
    
            Dim cmd As OleDbCommand = New OleDbCommand(query, cn)
    
            cmd.Parameters.AddWithValue("@startperiod", pStart)
            cmd.Parameters.AddWithValue("@endperiod", pEnd))
    ...
    Could the VB.net datetime type possibly not be compatible with the access Int() function?
    IMO there's two things wrong with this:

    1) bad advice from si_the_geek
    ... (because the Int() Function will enforce a FullTable-Scan, ignoring potentially defined Indexes on your Date-Column)

    2) not taking into account, that you work against an OleAutomation-Object in the end (an OleDB-Driver)
    ... (the .NET-Date-Type should better be passed as a Double, using the aptly named method: .ToOADate)

    So, here's what I think should work better (untested, don't use .NET here on this machine):

    Code:
    Dim query As String = "SELECT * FROM Shifts WHERE StartTime BETWEEN @startperiod AND @endperiod;"
    
    Dim pStart As Date = New DateTime(2023, 3, 1)
    Dim pEnd   As Date = New DateTime(2023, 3, 15).AddMilliSeconds(86400000-1)
    Dim cmd As OleDbCommand = New OleDbCommand(query, cn)
    
    cmd.Parameters.AddWithValue("@startperiod", pStart.ToOADate())
    cmd.Parameters.AddWithValue("@endperiod", pEnd.ToOADate())
    Edit: Just in case pStart and pEnd are passed "from outside"
    (where you cannot be sure, whether those Date-Values contain "fractions of a day"),
    then it'd be better, to do the truncation and millisecond-adding directly within the param-assignment-lines:
    Code:
    cmd.Parameters.AddWithValue("@startperiod", pStart.Date.ToOADate)
    cmd.Parameters.AddWithValue("@endperiod", pEnd.Date.AddMilliSeconds(86400000-1).ToOADate)
    HTH

    Olaf
    Last edited by Schmidt; Mar 19th, 2023 at 07:01 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width