我正在使用Delphi 7中的搜索查询功能(使用Paradox数据库),并且在两个日期之间选择时,我不断收到类型不匹配错误。如果我使用日期类型我
Project Project1.Exe引发异常类EDBEngineError,消息“表达式中的类型不匹配。”。流程停止。'
如果我使用dateTime类型,我会
Project Project1.Exe引发异常类EDBEngineError,并显示消息“无效使用关键字”。令牌:13? AND行号: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,'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
...
答案 0 :(得分:8)
这些行可能导致问题:
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 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;
或者,如果Query组件在分配SQL语句时自动填充Params
集合:
Query1.Params.ParamByName('Search').AsInteger := StrToInt(Search1);
Query1.Params.ParamByName('date1').AsDateTime := datum;
Query1.Params.ParamByName('date2').AsDateTime := datumzoek;
这样你就不必担心划分值了:组件会处理这个问题。