Home > Software engineering >  How do I write the SQL to retrieve records for a single date from Access database using C#
How do I write the SQL to retrieve records for a single date from Access database using C#

Time:06-04

I can retrieve all of the records between two dates from an Access database using this statement;

"SELECT DISTINCT ID_1 as SampleID, ID_2 as TestID FROM Results WHERE TestDate Between #"  
                        startDate.ToString("MM/dd/yyyy")   "# AND #"   endDate.ToString("MM/dd/yyyy")   "#"

but when I try to get a single date I get no records.

"SELECT DISTINCT ID_1 as SampleID, ID_2 as TestID FROM Results WHERE TestDate = #"  
                        startDate.ToString("MM/dd/yyyy")   "#";

The first attempt did not include the time which is part of the Date field in the data base. So I tried to format the date to include time in HH:mm:ss but that also returned 0 records.

What is wrong with the sql statement? This is an Access database.

CodePudding user response:

Assuming OleDB:

var SQL = @"
SELECT DISTINCT ID_1 as SampleID, ID_2 as TestID 
FROM Results 
WHERE TestDate >= ? AND TestDate < ?";

var cmd = new OleDbCommand(SQL);
cmd.Parameters.Add("?", OleDbType.Date).Value = startDate.Date;
cmd.Parameters.Add("?", OldDbType.Date).Value = startDate.Date.AddDays(1);

If you're using ODBC it will look similar, with just slightly different naming for the command and enum.

Some things of note:

  • Never never NEVER use string concatenation to put data in queries! I can't emphasize enough how important this is! Not only is it faster and helps you avoid basic data issues like someone who's last name is O'Brien or (ahem) correctly formatting your date literals, but failing to do this is the easiest way I know to find out a year from now that you were hacked six months ago.
  • If you ever find yourself trying to format a date string in code for use in an SQL query, you're doing something horribly wrong. Use the C# datetime type and let ADO.Net handle this for you via parameterized query.
  • Prefer separate conditions over BETWEEN for date ranges covering full days, with the inclusive >= on the lower bound and the exclusive < for the day after the upper bound. This can sometimes be faster, bust mostly it's just more correct around the boundaries, where BETWEEN can sometimes give the wrong results if you are not careful on how you structure your data and write your boundaries.

CodePudding user response:

You could strip the time part:

"SELECT DISTINCT ID_1 as SampleID, ID_2 as TestID FROM Results "  
"WHERE Fix(TestDate) = #"   startDate.ToString("yyyy'/'MM'/'dd")   "#";

or use an interval:

"SELECT DISTINCT ID_1 as SampleID, ID_2 as TestID FROM Results "  
"WHERE TestDate >= #"   startDate.ToString("yyyy'/'MM'/'dd")   "# and "  
"TestDate < #"   startDate.AddDays(1).ToString("yyyy'/'MM'/'dd")   "#";
  • Related