Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Query works in Workbench but get 'Could not convert variant type' error with the exact same query in Delphi

The exact error i'm getting is

Could not convert variant of type (UnicodeString) into type(Date).

The variable I am using for the date is a string and I have to place quotation marks around it or else it returns null but when I put the quotation marks around it I get this error.

Here is my code for the SQL Query and the variable TodaysDate. (This code isn't copy and pasted due to it being on a different machine without internet capabilities so please ignore anything that might cause a compiling error)

    if MidStr(DateToStr(Date),2,1) ='/' then
         TodaysDate := MidStr(DateToStr(Date),6,4) + '-' + '0' + 
         MidStr(DateToStr(Date),1,1) + '-' + MidStr(DateToStr(Date),3,2)
    else
      TodaysDate := MidStr(DateToStr(Date),7,4) + '-' 
      + MidStr(DateToStr(Date),1,2) + '-' + MidStr(DateToStr(Date),4,2);

   ADOQuery1.SQL.Clear;
   ADOQuery1.SQL.Add('SELECT tbl.emailAddress, tbljob.Time FROM '+
   'dbwindowwash.tblclient, dbwindowwash.tbljob, dbwindowash.tbljobclientworker '+
   'WHERE tbljobclientworker.jobID = tbljob.jobID AND '+
   'tbljobclientworker.clientID = tblclient.clientID AND tbljob.Date = ' +
   QuotedStr(TodaysDate));
   ADOQuery1.Open

   // More Code using the email addresses and time

Copy and pasted straight into the Workbench this query gives me all the data I want but in Delphi gives me and error and with no QuotedStr() it returns null in both Delphi and Workbench.

I have a similar query in my program elsewhere which uses the date as a string with QuotedStr() and it works fine so I have absolutely no idea what is wrong with this.

like image 338
TwoRice Avatar asked Dec 20 '25 23:12

TwoRice


1 Answers

Agreeing with SirRufo's comment here. The correct answer to "how do I do this?" is "don't do that; that's the wrong way to do it."

If you stick values directly into the query like that, hackers can find a way to place things into your query that get interpreted as SQL commands. This is known as SQL injection, and it's been responsible for billions of dollars' worth of damage in the last few decades. (Not exaggerating.)

The right way to do it is by cleanly separating your SQL code from your data, by using parameters, like so:

ADOQuery1.SQL.Clear;

//: before an identifier specifies a parameter
ADOQuery1.SQL.Add('SELECT tbl.emailAddress, tbljob.Time FROM '+
  'dbwindowwash.tblclient, dbwindowwash.tbljob, dbwindowash.tbljobclientworker '+
  'WHERE tbljobclientworker.jobID = tbljob.jobID AND '+
  'tbljobclientworker.clientID = tblclient.clientID AND tbljob.Date = :date';

//parse the query and find parameter declarations
ADOQuery1.Prepare;

//set a value for the parameter
ADOQuery1.ParamByName['date'].AsDateTime := TodaysDate;

ADOQuery1.Open

The exact syntax for how to set the value of a parameter may differ from one dataset type to another, but that should give you the basic idea.

like image 86
Mason Wheeler Avatar answered Dec 23 '25 21:12

Mason Wheeler