.Locate 中的 ADO vs Firedac 引用标志

ADO vs Firedac quote signs in .Locate

我们正在将近 200 万行代码从 BDE 迁移到 Delphi XE5(即将成为 DX)中的 SQL 服务器。

我们遇到了一个大问题。

我们一直在使用 ADO,但刚刚被 Microsoft 未能实现 .Locate 定位到同时具有单引号和井号的字符串上。示例:

TADOQuery1.Locate('FieldName', '2x4'' 10#', []) 

失败:

Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.

Microsoft 的 ADO 文档指出这将失败。我们可以在 ADODB.pas 中看到它的发生。对于简单的一个变量定位和包含多个变量的定位。

由于 WHERE 字符串处于紧密循环中,我们无法在标准查询中执行这些定位。

问题:FireDAC有这个问题吗?有人可以帮我们一个忙,实际尝试一下上面的 .Locate in FireDac 吗?

从 ADO 迁移到 Firedac 时,我们可能会遇到什么不愉快的"surprises"?

谢谢。

我在 XE8 中创建了一个极简主义的 FireDAC 应用程序,其中包含 TFDConnectionTFDQueryTFDGUIxWaitCursorTFDquery 连接到 TDataSourceTDBGridTDBNavigator。我将 TFDConnection 连接到 MS SqlServer 2014 数据库,并编辑了一个数据行以包含您的测试值

2x4' 10#

在 VARCHAR(80) 列中。

调用 .First,然后 FDQuery.Locate 成功定位了该行,当我仅在包含您的测试值的列上调用 .Locate 时是两场通话的一部分。

所以,至少值得你自己测试一下。您在上周的类似 Locate 查询中提到您使用了 XE8。

至于其他不愉快的意外,我想不起来了。我只记得当我们在 2002 年左右通过 OLEDB 驱动程序 + Ado 放弃 BDE 以支持 Sql Server 2000 时,摆脱 BDE 是一种幸运的解脱。我很高兴我们选择了我们所做的排序规则,Latin1_General_CI_AI,其中 CI = 不区分大小写,AI = 不区分重音。

我对 FireDAC 的主要保留意见是,虽然它处理这些事情似乎比 'native' 对象(如 Tadoxxx 对象)更好,但它似乎从它们中抽象出来,我怀疑你可能很难得到万一您确实遇到了一些问题,官方对此所做的任何事情。当然,它现在在 EMBA 手中,这可能会说一些关于从他们那里挤出错误修复的事情(特别是因为他们现在似乎将错误修复更新限制在更新订阅中),尽管作者似乎非常积极地支持它在线.

顺便说一句,我不确定您的 "Microsoft's failure" 依据是什么观察结果。我测试了 AdoQuery.Locate 并修改了 ADODB.Pas' GetFilterExpr 我在我对你的其他问题的回答中发布了它并且它工作正常,所以也许你是基于其他东西。

作为一个有趣的问题,我决定看看 ADOInt.Pas Recordset 对象是否可以用来做类似于 Locate 的事情,它可以而且也可以很好地与你的搜索值 2x4' 10# 以及我使用的其他测试模式:

procedure TForm1.TestRecordSetFind;
var
  Expr : String;
begin
  Expr := 'applicant = ' + QuotedStr(edLocate.Text);
  if cbMultiField.Checked then begin
    Expr := '(' + Expr + ') and (country = ''EP'')';
  end;
  Memo1.Lines.Add(Expr);
  AdoQuery1.RecordSet.Find(Expr, 0, adSearchForward, adBookmarkFirst);
  AdoQuery1.Resync([]);
end;

这样做有几个明显的局限性,当然,RecordSet.Find 是一个过程而不是一个返回布尔值的函数,而且它不区分大小写(尽管那是不是因为我的服务器排序规则,我不知道)。