gpt4 book ai didi

sql - 当我在 SQL 中输入日期值时,为什么会得到 "type mismatch"?

转载 作者:行者123 更新时间:2023-12-03 01:01:23 25 4
gpt4 key购买 nike

我正在 Delphi 7 中开发搜索查询功能(使用 Paradox 数据库),并且在两个日期之间进行选择时不断收到类型不匹配错误。如果我使用日期类型,我会得到

Project Project1.Exe raised exception class EDBEngineError with message 'Type mismatch in expression.'. Process stoped.'

如果我使用 dateTime 类型,我会得到

Project Project1.Exe raised exception class EDBEngineError with message 'Invalid use of keyword. Token : 13? AND Line Number: 8'. Process stoped.'

其中 13 是时间的第一位数字。

这是我的代码:

procedure TForm1.Button1Click(Sender: TObject);
var
Search1 :string;
Search2 :string;
outputveld : string;
datum : TDateTime;
datumZoek: TdateTime;
countmails : integer;
outfile: textfile;
Zoek6MaandenTerug: Double;
begin
Zoek6MaandenTerug := 182.621099;
datum := tdate(now);
datumZoek := datum - Zoek6MaandenTerug;
ShowMessage(DateTimeToStr(Datum));
ShowMessage(DateTimeToStr(datumZoek));
Memo1.Lines.Add(DateTimeToStr(Datum));
//datum := datum- StrToDate('21-4-2004');
{radio button date controll}

{//radio button date controll}
Search1 := Edit1.Text;
Search2 := Edit2.Text;

assignfile(outfile,'text\Emails.txt');
rewrite(outfile);
outputveld := '';
countmails := 0;

{sets up and executesSQL query(Query1)}
Query1.close;
Query1.SQL.Clear;
memo1.Clear;
if Search1 <> EmptyStr then
begin
//Query1.SQL.add('SELECT * FROM Verkoop');
Query1.SQL.add('SELECT DISTINCT Verkoophandelingen.Klantnr, Verkoophandelingen.Type, verkoop.Klantnr, Verkoop.Artikelnr, Artikels.Nummer, Artikels.artikelgroep, Verkoophandelingen.Datum, Klanten.Email');
Query1.SQL.add('FROM Verkoop');
Query1.SQL.add('full Join Artikels ON Verkoop.Artikelnr = Artikels.Nummer');
Query1.SQL.add('full Join Klanten ON Verkoop.Klantnr = Klanten.Nummer');
Query1.SQL.add('full Join Verkoophandelingen ON Verkoop.verkoophandelingnr = Verkoophandelingen.nummer');
Query1.SQL.add('WHERE Verkoophandelingen.Type = "Bestelling" ');
Query1.SQL.add('AND Verkoop.Artikelnr = '+Search1+'');
//Query1.SQL.add('AND Verkoophandelingen.Datum = '+ DateToStr(Date1) +'');
Query1.SQL.add('AND Verkoophandelingen.Datum BETWEEN '+DateTimeToStr(datum)+'');
Query1.SQL.Add('AND '+DateToStr(datumzoek)+'');
Query1.SQL.add('ORDER BY Datum');

Query1.RequestLive := true;
Query1.open;
end
else if Search2 <> EmptyStr then
begin
Query1.SQL.add('SELECT DISTINCT Verkoophandelingen.Klantnr, Verkoophandelingen.Type, verkoop.Klantnr, Verkoop.Artikelnr, Artikels.Nummer, Artikels.artikelgroep, Verkoophandelingen.Datum, Klanten.Email');
Query1.SQL.add('FROM Verkoop');
Query1.SQL.add('full Join Artikels ON Verkoop.Artikelnr = Artikels.Nummer');
Query1.SQL.add('full Join Klanten ON Verkoop.Klantnr = Klanten.Nummer');
Query1.SQL.add('full Join Verkoophandelingen ON Verkoop.verkoophandelingnr = Verkoophandelingen.nummer');
Query1.SQL.add('WHERE Verkoophandelingen.Type = "Bestelling" ');
Query1.SQL.add('AND Artikels.ArtikelGroep = '+Search2+'');
Query1.SQL.add('AND Verkoophandelingen.Datum BETWEEN '+DateToStr(datum)+'');
Query1.SQL.Add('AND '+DateToStr(datumZoek)+'');
Query1.SQL.add('ORDER BY Datum');
Query1.RequestLive := true;
Query1.open;
end;

while not Query1.Eof do
begin
if Query1.FieldByName('Email').AsString <> EmptyStr then
begin
memo1.Lines.Add(Query1.FieldByName('Email').AsString + ';');
writeln(outfile, Query1.FieldByName('Email').AsString+ ';');
Query1.next;
inc(countmails);
end
else
begin
Query1.next;
end;
end;

if Query1.Eof then
begin
CloseFile(outfile);
memo1.lines.add('totaal aantal valid email adressen = ' + IntToStr(countmails));
end;
end;
<小时/>

我希望我在正确的地方发帖。这是我为查询添加参数后仍然得到的代码“表达式中的类型不匹配。”

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGrids, DB, DBTables, DBCtrls;

type
TForm1 = class(TForm)
DataSource1: TDataSource;
Query1: TQuery;
DBGrid1: TDBGrid;
Button1: TButton;
ComboBox1: TComboBox;
Memo1: TMemo;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Button2: TButton;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
RadioButton3: TRadioButton;
procedure Button1Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure ComboBox1Change(Sender:TObject);
procedure Edit1Change(Sender: TObject);
procedure Edit2Change(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses ComObj;

{$R *.dfm}




procedure TForm1.FormActivate(Sender: TObject);

var
i : integer;
mystringlist : tstringlist;
datum: TDateTime;
Zoek6MaandenTerug : Double;
begin
Zoek6MaandenTerug := 182.621099;
datum := tdate(now);
datum := datum - Zoek6MaandenTerug;
ShowMessage(DateToStr(datum));
Memo1.Lines.Add(DateTimeToStr(Datum));
Memo1.Lines.Add(DateToStr(datum));
//datum := datum- StrToDate('21-4-2004');

MyStringList := TStringList.Create;
{
memo1.Clear;
Edit1.Clear;
Edit2.Clear;
}

try
Session.GetAliasNames(MyStringList);
{ fill a list box with alias names for the user to select from }
for I := 0 to MyStringList.Count - 1 do begin
combobox1.Items.Add(MyStringList[I]);
end
finally
MyStringList.Free;
end;

end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin

try
Query1.SQL.Clear;
Query1.Databasename := string(combobox1.items[combobox1.ItemIndex]);

except
with Application do
begin
NormalizeTopMosts;
MessageBox(' wrong database ', 'fout..', MB_OK);
RestoreTopMosts;
combobox1.SetFocus;
Exit;
end;

end;
end;



procedure TForm1.Button1Click(Sender: TObject);
var

Search1 :String;
Search2 :String;
outputveld : string;
datum : TDateTime;
datumZoek: TDateTime;
countmails : integer;
outfile: textfile;
Zoek6MaandenTerug: Double;

begin

Zoek6MaandenTerug := 182.621099;
datum := tdate(now);
datumZoek := datum - Zoek6MaandenTerug;
ShowMessage(DateTimeToStr(Datum));
ShowMessage(DateTimeToStr(datumZoek));
Memo1.Lines.Add(DateToStr(datum));
Memo1.Lines.Add(DateToStr(datumZoek));

//datum := datum- StrToDate('21-4-2004');



{//radio button date controll}
Search1 := Edit1.Text;
Search2 := Edit2.Text;


assignfile(outfile,'text\Emails.txt');
rewrite(outfile);
outputveld := '';
countmails := 0;


{sets up and executesSQL query(Query1)}
Query1.close;
Query1.SQL.Clear;
memo1.Clear;
if Search1 <> EmptyStr then
begin


//Query1.SQL.add('SELECT * FROM Verkoop');
Query1.SQL.add('SELECT DISTINCT Verkoophandelingen.Klantnr, Verkoophandelingen.Type, verkoop.Klantnr, Verkoop.Artikelnr, Artikels.Nummer, Artikels.artikelgroep, Verkoophandelingen.Datum, Klanten.Email');
Query1.SQL.add('FROM Verkoop');
Query1.SQL.add('full Join Artikels ON Verkoop.Artikelnr = Artikels.Nummer');
Query1.SQL.add('full Join Klanten ON Verkoop.Klantnr = Klanten.Nummer');
Query1.SQL.add('full Join Verkoophandelingen ON Verkoop.verkoophandelingnr = Verkoophandelingen.nummer');
Query1.SQL.add('WHERE Verkoophandelingen.Type = "Bestelling" ');
Query1.SQL.add('AND Verkoop.Artikelnr = :Search1');
//Query1.SQL.add('AND Verkoophandelingen.Datum = '+ DateToStr(Date1) +'');
Query1.SQL.add('AND Verkoophandelingen.Datum BETWEEN :datum AND :datumzoek');


Query1.SQL.add('ORDER BY Datum');


Query1.ParamByName('datumzoek').Value := datumzoek;
Query1.ParamByName('datum').Value := datum;
Query1.ParamByName('Search1').Value := Search1;

Query1.RequestLive := true;
Query1.open;

end
else if Search2 <> EmptyStr then
begin

Query1.SQL.add('SELECT DISTINCT Verkoophandelingen.Klantnr, Verkoophandelingen.Type, verkoop.Klantnr, Verkoop.Artikelnr, Artikels.Nummer, Artikels.artikelgroep, Verkoophandelingen.Datum, Klanten.Email');
Query1.SQL.add('FROM Verkoop');
Query1.SQL.add('full Join Artikels ON Verkoop.Artikelnr = Artikels.Nummer');
Query1.SQL.add('full Join Klanten ON Verkoop.Klantnr = Klanten.Nummer');
Query1.SQL.add('full Join Verkoophandelingen ON Verkoop.verkoophandelingnr = Verkoophandelingen.nummer');
Query1.SQL.add('WHERE Verkoophandelingen.Type = "Bestelling" ');
Query1.SQL.add('AND Artikels.ArtikelGroep = :Search2');
//Query1.SQL.add('AND Verkoophandelingen.Datum BETWEEN '+DateToStr(datum)+'');
//Query1.SQL.Add('AND '+DateToStr(datumZoek)+'');

Query1.SQL.add('AND Verkoophandelingen.Datum BETWEEN :datum AND :datumzoek');

Query1.SQL.add('ORDER BY Datum');

Query1.ParamByName('datumzoek').Value := datumzoek;
Query1.ParamByName('datum').Value := datum;
Query1.ParamByName('Search2').Value := Search2;

Query1.RequestLive := true;
Query1.open;

end;




while not Query1.Eof do
begin
if Query1.FieldByName('Email').AsString <> EmptyStr then
begin
memo1.Lines.Add(Query1.FieldByName('Email').AsString + ';');
writeln(outfile, Query1.FieldByName('Email').AsString+ ';');
Query1.next;
inc(countmails);
end

else
begin
Query1.next;
end;
end;

if Query1.Eof then
begin
CloseFile(outfile);
memo1.lines.add('totaal aantal valid email adressen = ' + IntToStr(countmails));

end;

end;





procedure TForm1.Edit1Change(Sender: TObject);
begin
Edit2.Text := '';
end;

procedure TForm1.Edit2Change(Sender: TObject);
begin
Edit1.Text := '';
end;


end.
<小时/>

添加此后

        ... 
Query1.ParamByName('datumzoek').DataType := ftDate;
Query1.ParamByName('datum').DataType := ftDate;
Query1.ParamByName('Search1').DataType := ftInteger;

Query1.ParamByName('datumzoek').Value := datumzoek;
Query1.ParamByName('datum').Value := datum;
Query1.ParamByName('Search1').Value := Search1;
...

查询运行但没有结果,显示查询后,文本似乎参数有一个“?”值?

...
SELECT DISTINCT Verkoophandelingen.Klantnr, Verkoophandelingen.Type, verkoop.Klantnr, Verkoop.Artikelnr, Artikels.Nummer, Artikels.artikelgroep, Verkoophandelingen.Datum, Klanten.Email
FROM Verkoop
full Join Artikels ON Verkoop.Artikelnr = Artikels.Nummer
full Join Klanten ON Verkoop.Klantnr = Klanten.Nummer
full Join Verkoophandelingen ON Verkoop.verkoophandelingnr = Verkoophandelingen.nummer
WHERE Verkoophandelingen.Type = "Bestelling"
AND Verkoop.Artikelnr = ?
AND Verkoophandelingen.Datum BETWEEN ? AND ?
ORDER BY Datum
...

最佳答案

也许这些行导致了问题:

Query1.SQL.add('AND Verkoophandelingen.Datum BETWEEN '+DateTimeToStr(datum)+'');
Query1.SQL.Add('AND '+DateToStr(datumzoek)+'');

在这里,您将插入 DateTimeToStrDateToStr 返回的日期,但您不会以任何方式分隔插入的值,因此生成的查询将类似于这个:

...
AND Verkoophandelingen.Datum BETWEEN 21-04-2004
AND 22-04-2004
...

我不确定 Paradox 使用什么分隔符来表示日期常量,但我几乎确定它确实使用了一些分隔符。也许,应该是':

...
AND Verkoophandelingen.Datum BETWEEN '21-04-2004'
AND '22-04-2004'
...

查看手册以找到正确的代码并相应地修复您的代码。

另一方面,使用参数化查询会是一个更好的主意,正如 @Rob Kennedy 所正确建议的那样。在参数化查询中,您可以使用 :name 等占位符来代替参数值。因此,在您的情况下,它可能看起来像这样:

...
Query1.SQL.add('WHERE Verkoophandelingen.Type = "Bestelling" ');
Query1.SQL.add('AND Verkoop.Artikelnr = :Search');
Query1.SQL.add('AND Verkoophandelingen.Datum BETWEEN :date1');
Query1.SQL.Add('AND :date2');
...

在运行查询之前,您需要使用 TQuery.Params 属性设置参数,如下所示:

Query1.Params.CreateParam(ftInteger, 'Search', ptInput).AsInteger := StrToInt(Search1);
Query1.Params.CreateParam(ftDateTime, 'date1', ptInput).AsDateTime := datum;
Query1.Params.CreateParam(ftDateTime, 'date2', ptInput).AsDateTime := datumzoek;

或者,如果查询组件在分配 SQL 语句时自动填充 Params 集合:

Query1.Params.ParamByName('Search').AsInteger := StrToInt(Search1);
Query1.Params.ParamByName('date1').AsDateTime := datum;
Query1.Params.ParamByName('date2').AsDateTime := datumzoek;

这样您就不需要担心分隔值:组件会处理这个问题。

关于sql - 当我在 SQL 中输入日期值时,为什么会得到 "type mismatch"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14604210/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com