【问题标题】:Common Table Expression Error公用表表达式错误
【发布时间】:2011-01-12 04:24:32
【问题描述】:

我必须使用老式 ADODB(不是 ADO.NET)来执行包含公用表表达式的语句。 我正在使用(必须使用)SQLOLEDB 提供程序。 DML 语句在从 Windows 7 / Windows Server 2008 客户端而不是从 WinXP 或 Win2K3 服务器执行时工作正常。 我分析了该例程,发现旧操作系统发送的 SQL 语句略有不同。

Win7 + 2008 =    exec sp_executesql N'WITH source(Vsl, Cpt, SrcTyp, SrcNum, Opn, JobNum, Qty, Cst, Vry, Reg, Vnt, Sbk) AS ...'

WinXP + Win2K3 = exec sp_executesql N'exec WITH source(Vsl, Cpt, SrcTyp, SrcNum, Opn, JobNum, Qty, Cst, Vry, Reg, Vnt, Sbk) AS ...'

请注意额外的 'exec' 滑入命令文本中。

看起来好像旧操作系统上的 SQLOLEDB.1 版本错误地处理了 WITH 语句,并认为它需要一个前置“exec”。

任何人都可以对此有所了解。是否有可以应用于旧操作系统的 SQLOLEDB 驱动程序更新?或其他一些解决方法。

【问题讨论】:

  • 详细帮助 -- 如果 CTE 不是递归的,那么无论如何都没有任何好处,因此您可以将其重写为派生表/内联视图。
  • 咳嗽存储过程咳嗽

标签: sql windows-xp ado common-table-expression


【解决方案1】:

(仅供参考,您真的应该重新审视您现有的一些问题,因为它们中的大多数似乎都有解决问题的有用答案;您的 cmets 甚至建议是这样。如果他们有答案,请接受) .

如果您真的需要在这里使用 CTE(这意味着您正在做一些递归的事情,并且不仅仅是为了方便而不是内联选择或内联加入),最简单和最快的解决方法可能是包含您自己调用sp_executesql 中的SQL。你最终会嵌套调用它(这看起来很傻),但它不应该导致任何实际问题。

【讨论】:

    【解决方案2】:

    如果查询中没有参数,则将查询包装在 sp_executesql 语句中效果很好,否则参数不会被解析,因为它们在到达 ADO 时就在带引号的字符串中,这会导致在语法错误中。

    我为解决这个问题所做的是创建一个 TADOQuery 后代,它会覆盖构造函数,如下所示:

    constructor TCPADOQuery.Create(AOwner: TComponent);
    begin
      inherited;
      TWideStringList(SQL).OnChange := LocalQueryChanged;
    end;
    

    LocalQueryChanged 然后检查查询是否以公用表表达式开头,并在查询的开头插入一个虚拟声明,XP ADO 解析器确实可以理解。如果 CTE 不是查询中的第一条语句,则必须在 CTE 前面加上分号,因此我们必须先解决这个问题:

    procedure TCPADOQuery.LocalQueryChanged(Sender: TObject);
    var
      a: WideString;
    begin
      if not (csLoading in ComponentState) then
        Close;
      a := Trim(SQL.Text);
      if Uppercase(copy(a, 1, 4)) = 'WITH' then a := ';' + a;
      if Uppercase(copy(a, 1, 5)) = ';WITH' then
        a := 'DECLARE @DummyForADO_XP BIT'#13#10 + a;
      CommandText := a;
    end;
    

    这已经解决了问题,并且让我不必在我同时使用 CTE 和参数的地方重新编写所有代码。

    【讨论】:

    • 虽然我没有在这里使用您的完整答案,但在语句开头添加虚拟声明以便 XP 解析器工作的技巧是天赐之物。支持 SQL Server 的 Access 前端,这让我抓狂。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 2012-11-12
    相关资源
    最近更新 更多