我在 delphi 中不断收到 "Data type mismatch in criteria expression" 错误
I keep getting "Data type mismatch in criteria expression" error in delphi
每当运行此代码时,我都会收到上述错误。该代码应该在 table 中插入一条记录,然后从另一个 table.
中删除记录
for I := iMax - K to iMax do
begin
Inc(a);
with dmMenu.qryMcDonalds do
begin
SQL.Text :=
'SELECT ID, ItemID, ItemPrice, ItemCategory FROM tblCheckout WHERE ID = ' + IntToStr(I);
Open;
sItemID := Fields[1].AsString;
rItemPrice := Fields[2].AsFloat;
sItemCategory := Fields[3].AsString;
ShowMessage(IntToStr(I));
// I get the error here
SQL.Text :=
'INSERT INTO tblOrderItems (OrderItemID, OrderID, ItemID, ItemCategory, ItemPrice) VALUES ("' + sOrderID + '_' + IntToStr(a) + '"' + ', "' + sOrderID + '", "' + sItemID + '", "' + sItemCategory + '", "' + FloatToStrF(rItemPrice, ffCurrency, 10, 2) + '")';
ExecSQL;
SQL.Text := 'DELETE FROM tblCheckout WHERE ID = ' + IntToStr(I);
ExecSQL;
end; // with SQL
end; // for I
编辑:我认为问题出在 'INSERT INTO' 部分。除了最后一列,所有列都是短文本,ItemPrice 是一种货币。我也在使用 Access
请在主窗体上仅使用以下项目开始一个新项目:
- 配置为连接到您的数据库的 TAdoConnection;
- 配置为使用 TAdoConnection 的 TAdoQuery
- 配置为显示 TAdoQuery 内容的 TDataSource 和 TDBGrid。
然后,在表单中添加以下代码
const
sSelect = 'select * from tblOrderItems';
sInsert = 'insert into tblOrderItems(OrderItemID, OrderID, ItemID, ItemCategory, ItemPrice) '#13#10
+ 'values(:OrderItemID, :OrderID, :ItemID, :ItemCategory, :ItemPrice)';
sOrderItemID = '0999';
sOrderID = '1999';
sItemID = '2999';
sItemCategory = 'Bolt';
fItemPrice = 5.99;
procedure TForm2.FormCreate(Sender: TObject);
begin
AdoQuery1.SQL.Text := sInsert;
AdoQuery1.Prepared := True;
AdoQuery1.Parameters.ParamByName('OrderItemID').Value:= sOrderItemID;
AdoQuery1.Parameters.ParamByName('OrderID').Value := sOrderID;
AdoQuery1.Parameters.ParamByName('ItemID').Value := sItemID;
AdoQuery1.Parameters.ParamByName('ItemCategory').Value := sItemCategory;
AdoQuery1.Parameters.ParamByName('ItemPrice').Value := fItemPrice;
AdoQuery1.ExecSQL;
AdoQuery1.SQL.Text := sSelect;
AdoQuery1.Open;
end;
在编译和 运行ning 程序之前,检查并更改常量的值
这样它们就不会与您的 table.
中已有的任何行发生冲突
常量 sInsert 在 Values
中定义了所谓的“参数化 SQL 语句”
列表中的项目:OrderItemID、:OrderID 等是 AdoQuery 将变成的占位符
您可以在 运行 时间提供其值的参数,如在 AdoQuery1.Parameters.ParamByName(...
之后的块中
你应该总是以这种方式构造SQL语句,不通过连接字符串
正如您的代码尝试做的那样。它更不容易出错,因为它很容易进入
如果您使用 DIY 代码,语法混乱,它还确保您的查询不容易
Sql-Injection exploits,如果你
让用户有机会编辑 SQL.
如果您使用的是 FireDAC FDQuery,则它具有 Params
(FD 数据类型)而不是参数
但它们的工作方式几乎相同 - 请参阅联机帮助。
以后,请更加小心,确保包含重要的细节,尤其是发生错误的 exact 行 - 您可以通过单步执行检查通过使用调试器的代码 - 以及您正在使用的确切的数据库访问组件之类的东西。还要尝试正确获取详细信息,例如列是“短文本”类型还是自动编号。
对于需要调试的问题,比如这个问题,您还应该提供完整的,minimal, reproducible example,而不仅仅是一段代码。很多时候,你会在准备mre的时候意识到问题出在哪里,所以它对你和我们都有帮助。
我敢打赌问题出在不兼容的浮点格式上。
使用参数来避免它。
每当运行此代码时,我都会收到上述错误。该代码应该在 table 中插入一条记录,然后从另一个 table.
中删除记录for I := iMax - K to iMax do
begin
Inc(a);
with dmMenu.qryMcDonalds do
begin
SQL.Text :=
'SELECT ID, ItemID, ItemPrice, ItemCategory FROM tblCheckout WHERE ID = ' + IntToStr(I);
Open;
sItemID := Fields[1].AsString;
rItemPrice := Fields[2].AsFloat;
sItemCategory := Fields[3].AsString;
ShowMessage(IntToStr(I));
// I get the error here
SQL.Text :=
'INSERT INTO tblOrderItems (OrderItemID, OrderID, ItemID, ItemCategory, ItemPrice) VALUES ("' + sOrderID + '_' + IntToStr(a) + '"' + ', "' + sOrderID + '", "' + sItemID + '", "' + sItemCategory + '", "' + FloatToStrF(rItemPrice, ffCurrency, 10, 2) + '")';
ExecSQL;
SQL.Text := 'DELETE FROM tblCheckout WHERE ID = ' + IntToStr(I);
ExecSQL;
end; // with SQL
end; // for I
编辑:我认为问题出在 'INSERT INTO' 部分。除了最后一列,所有列都是短文本,ItemPrice 是一种货币。我也在使用 Access
请在主窗体上仅使用以下项目开始一个新项目:
- 配置为连接到您的数据库的 TAdoConnection;
- 配置为使用 TAdoConnection 的 TAdoQuery
- 配置为显示 TAdoQuery 内容的 TDataSource 和 TDBGrid。
然后,在表单中添加以下代码
const
sSelect = 'select * from tblOrderItems';
sInsert = 'insert into tblOrderItems(OrderItemID, OrderID, ItemID, ItemCategory, ItemPrice) '#13#10
+ 'values(:OrderItemID, :OrderID, :ItemID, :ItemCategory, :ItemPrice)';
sOrderItemID = '0999';
sOrderID = '1999';
sItemID = '2999';
sItemCategory = 'Bolt';
fItemPrice = 5.99;
procedure TForm2.FormCreate(Sender: TObject);
begin
AdoQuery1.SQL.Text := sInsert;
AdoQuery1.Prepared := True;
AdoQuery1.Parameters.ParamByName('OrderItemID').Value:= sOrderItemID;
AdoQuery1.Parameters.ParamByName('OrderID').Value := sOrderID;
AdoQuery1.Parameters.ParamByName('ItemID').Value := sItemID;
AdoQuery1.Parameters.ParamByName('ItemCategory').Value := sItemCategory;
AdoQuery1.Parameters.ParamByName('ItemPrice').Value := fItemPrice;
AdoQuery1.ExecSQL;
AdoQuery1.SQL.Text := sSelect;
AdoQuery1.Open;
end;
在编译和 运行ning 程序之前,检查并更改常量的值 这样它们就不会与您的 table.
中已有的任何行发生冲突常量 sInsert 在 Values
中定义了所谓的“参数化 SQL 语句”
列表中的项目:OrderItemID、:OrderID 等是 AdoQuery 将变成的占位符
您可以在 运行 时间提供其值的参数,如在 AdoQuery1.Parameters.ParamByName(...
你应该总是以这种方式构造SQL语句,不通过连接字符串 正如您的代码尝试做的那样。它更不容易出错,因为它很容易进入 如果您使用 DIY 代码,语法混乱,它还确保您的查询不容易 Sql-Injection exploits,如果你 让用户有机会编辑 SQL.
如果您使用的是 FireDAC FDQuery,则它具有 Params
(FD 数据类型)而不是参数
但它们的工作方式几乎相同 - 请参阅联机帮助。
以后,请更加小心,确保包含重要的细节,尤其是发生错误的 exact 行 - 您可以通过单步执行检查通过使用调试器的代码 - 以及您正在使用的确切的数据库访问组件之类的东西。还要尝试正确获取详细信息,例如列是“短文本”类型还是自动编号。
对于需要调试的问题,比如这个问题,您还应该提供完整的,minimal, reproducible example,而不仅仅是一段代码。很多时候,你会在准备mre的时候意识到问题出在哪里,所以它对你和我们都有帮助。
我敢打赌问题出在不兼容的浮点格式上。 使用参数来避免它。