views:

798

answers:

2

Hi folks,

I have a date column in a DB tabel that I want to query using a date taken from textbox.text. the user selects a date from the calendar in the format dd/MM/yyyy. I want to use that date to put into a query. How do i format the date to be able to query the database?

  Dim datefrom As String =txtDateFrom.Text
  Dim dateto As String =txtDateTo.Text

The query will look like this:

  WHERE (tblClient.ClientID = " & ClientID & ") AND (tblBackupArchive.BackupDate BETWEEN '" + datefrom + "' AND '" + dateto + "')"

I'm using MS SQL Server btw. Any help most appreciated.

Jonesy

+5  A: 

NEVER USE STRING CONCATENATION LIKE THAT TO BUILD YOUR QUERIES!!!

And yes, I did mean to yell, because date formatting is the least of your problems. Imagine what would happen in your current code if something entered the following into one of your date textboxes:

';DROP TABLE tblClient;--

Instead, use a parameterized query. That will fix your date issues and protect against sql injection attacks. Here's an example:

Dim sql As String = " .... WHERE tblClient.ClientID= @ClientID AND tblBackupArchive.BackupDate >= @DateFrom AND tblBackupArchive.Backupdate < @DateTo"

Using cn As New SqlConnection("your connection string here"), _
      cmd As New SqlCommand(sql, cn)

    cmd.Parameters.Add("@ClientID", SqlDbType.Int).Value = ClientID
    cmd.Parameters.Add("@DateFrom", SqlDbType.DateTime).Value = DateTime.Parse(txtDateFrom.Text)
    cmd.Parameters.Add("@DateTo", SqlDbType.DateTime).Value = DateTime.Parse(txtDateTo.Text).AddDays(1)

    cn.Open()

    cmd.Execute___()

End Using

You can think of it now as if you had run an sql statement more like this:

DECLARE @ClientID Int
DECLARE @DateFrom DateTime
DECLARE @DateTo DateTime

Set @ClientID = ImaginaryFunctionToGetQueryData('ClientID')
Set @DateFrom = ImaginaryFunctionToGetQueryData('DateFrom')
Set @DateTo   = ImaginaryFunctionToGetQueryData('DateTo')

SELECT ... 
FROM ... 
WHERE tblClient.ClientID= @ClientID 
    AND tblBackupArchive.BackupDate >= @DateFrom 
    AND tblBackupArchive.Backupdate < @DateTo

The "ImaginaryFunction" in that code is accomplished using the sp_executesql stored procedure, but the point is that the query string as seen by sql server will never substitute data directly into the query string. Code is code, data is data, and never the 'twain shall meet.

Joel Coehoorn
strings and dates don't mix. Especially since you Americans put your days and months the wrong way round ;)
GordonB
@Joel. Thanks for the info, I hadn't though of that. Thankfully its just an application being used with the company. Does your example take into account british date formatting? I'll mark it as the answer if it does ;)
iamjonesy
thanks for the help. I've changed to ur suggestion but its not returning any rows. When i debug the cmd text is "...WHERE (tblClient.ClientID = @ClientID) AND (tblBackupArchive.BackupDate BETWEEN @datefrom AND @dateto). it hasn't changes to the parameters it would seem?
iamjonesy
The cmdtext won't change.But the sql that is executed on the sql server will contain the correct values.
GordonB
Run SQL Profiler, and see what is actually executed on the server.
GordonB
@Jonesy - the whole point of parameterized queries is that it _never_ substitutes the data into the query string. Data is data and code is code, and never the 'twain shall meet.
Joel Coehoorn
+1  A: 

Just as an addition to Joel's answer....

I'd avoid using any strings in the equation at all. IE; Don't use textboxes to store the dates, use proper calendar or datetimepickers.

This way, you won't have to do this;

cmd.Parameters.Add("@DateFrom", SqlDbType.DateTime).Value = DateTime.Parse(txtDateFrom.Text)

as Joel suggests, but instead you can just do;

cmd.Parameters.Add("@DateFrom", SqlDbType.DateTime).Value = dtDateFrom.value

This way your not reliant on the DateTime.parse actually picking the correct format from your string. And you'll only be using date types.

GordonB