SQL Query works in Workbench but get 'Could no

2019-01-28 07:11发布

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.

2条回答
干净又极端
2楼-- · 2019-01-28 07:50

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.

查看更多
3楼-- · 2019-01-28 08:04

If you want a date to work correctly in an SQL query don't go hobbying yourself but use the following format: yyyymmdd.

For instance april 3 2014 becomes: 20140403.

You do this easily with FormatDateTime, in your case:

TodaysDate := FormatDateTime('yyyymmdd', Date)

This date notation is iso compliant and you don't have to think about local settings anymore.

查看更多
登录 后发表回答