我正在 Delphi 7 中开发搜索查询函数(使用 Paradox 数据库),在两个日期之间进行选择时不断出现类型不匹配错误。如果我使用日期类型,我会得到
项目 Project1.Exe 引发了异常类 EDBEngineError,并显示消息"表达式中的类型不匹配"。进程已停止。
如果我使用日期时间类型,我会得到
项目 Project1.Exe 引发异常类 EDBEngineError,并显示消息"关键字使用无效。代币 : 13?和行号:8'。进程已停止。
其中 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,'textEmails.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,'textEmails.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)+'');
在这里,您插入了 DateTimeToStr
和 DateToStr
返回的日期,但您没有以任何方式分隔插入的值,因此生成的查询将如下所示:
...
AND Verkoophandelingen.Datum BETWEEN 21-04-2004
AND 22-04-2004
...
我不确定分隔符 Paradox 用于日期常量,但我几乎可以肯定它确实使用了一些。也许,应该是'
:
...
AND Verkoophandelingen.Datum BETWEEN '21-04-2004'
AND '22-04-2004'
...
检查手册是否正确,并相应地修复您的代码。
另一方面,正如肯尼迪@Rob正确建议的那样,使用参数化查询会是一个更好的主意。在参数化查询中,使用占位符,例如参数值应位于: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;
或者,如果 Query 组件在分配 SQL 语句时自动填充Params
集合:
Query1.Params.ParamByName('Search').AsInteger := StrToInt(Search1);
Query1.Params.ParamByName('date1').AsDateTime := datum;
Query1.Params.ParamByName('date2').AsDateTime := datumzoek;
这样你就不需要担心分隔值:组件将处理这个问题。