ADO 与 Firedac 报价登录 .Locate

Posted

技术标签:

【中文标题】ADO 与 Firedac 报价登录 .Locate【英文标题】:ADO vs Firedac quote signs in .Locate 【发布时间】:2015-09-28 18:55:24 【问题描述】:

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

我们遇到了一个大问题。

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

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

失败:

参数类型错误、超出可接受范围或相互冲突。

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

我们无法在标准查询中使用 WHERE 字符串进行这些定位,因为它们处于紧密循环中。

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

从 ADO 迁移到 Firedac 会遇到哪些令人不快的“惊喜”?

谢谢。

【问题讨论】:

您可以自己做这件事 - 只需获取 DX Seattle 的试用版并在 30 天内测试您喜欢的任何内容 我过去曾在这种情况下使用四单引号,因为 ADO 似乎也希望它们转义。前任。 TADOQuery1.Locate('FieldName', '2x4'''' 10#', []) 引号和井号被 ADO 拒绝,而不是 ADODB.pas。在 FireDAC 中,实现 Locate 的代码是在 Delphi 上编写的。而且它不关心搜索值内容。可能有你需要的任何东西。 【参考方案1】:

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

2x4' 10#

在 VARCHAR(80) 列中。

调用.First,然后FDQuery 中的.Locate 成功定位了该行,当我仅在包含您的测试值的列上调用.Locate 并且它是双字段调用的一部分时。

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

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

我对 FireDAC 的主要保留是,虽然它似乎比 TAdoxxx 之类的“原生”对象更好地处理这些事情,但它似乎与它们相去甚远,我怀疑你可能很难得到任何正式的东西不幸的是,您确实遇到了一些问题。当然,现在它掌握在 EMBA 手中,这可能会说明如何从他们身上榨取错误修复(特别是因为他们现在似乎将错误修复更新限制在更新订阅上的那些),尽管作者似乎非常积极地支持它在线。

顺便说一句,我不确定您是根据什么观察得出的“微软的失败”。我测试了 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 是一个过程而不是一个返回布尔值的函数,并且它不区分大小写(尽管这是否是因为我的服务器排序规则是,我不知道)。

【讨论】:

谢谢,MartyA。你帮了大忙。我们会查看您的建议。我们认为在 ADO 中不可能做到这一点的原因是在 support.microsoft.com/en-us/kb/245408,Microsoft 声明:“这些是一些复杂的标准,Find 或 Filter 无法处理。”然后列出:Description = "#3 Board 4" '"2' x 2''4"'

以上是关于ADO 与 Firedac 报价登录 .Locate的主要内容,如果未能解决你的问题,请参考以下文章

(FireDAC) 连接定义

Delphi:FireDac 连接阻止应用程序

SourceTree不出现用户登录窗口,提示错误fatal: unable to access'...'; error setting certificate verify locat

DataSnap与FireDAC三层

Delphi 和 Firedac:查询活动与查询打开

FireDac Firebird和Android