【问题标题】:Mystery Parametric SQL Query with joins + TClientDataSet blank fields带有连接的神秘参数 SQL 查询 + TClientDataSet 空白字段
【发布时间】:2014-01-04 12:01:00
【问题描述】:

有时,即使是显而易见的事情似乎也会出错。在处理 SQL 组件时,有很多明显的和肯定会出错的地方,当它们只是整个 SQLQuery => Provider => ClientDataSet => DataSource => DataControl 链的环时,甚至更多。

今天的例子非常愚蠢,但却是浪费时间。

如何复制它:

在其 SQL 中删除一个带有简单参数连接的 TZQuery (ZeosLib),例如:

SELECT
  pr.product_id AS product_id,
  pr.model AS model,
  pd.name AS name,
  pr.image AS image,
  pr.status AS status,
  pr.date_added AS date_added,
  pr.date_modified AS date_modified

FROM oc_product pr
LEFT JOIN oc_product_description pd 
  ON pr.product_id = pd.product_id AND pd.language_id = :language_id
WHERE
  pr.status = 1
ORDER BY
  pd.name

当然我们有一个参数,:language_id

然后删除一个链接到它的 TDataSetProvider,然后是一个 TClientDataSet,然后是一个 TDataSource,最后是一个 TDBGrid,所有这些都链接到前一个。最后删除一个 TDBNavigator 并链接它。

最后,在 TClientDataSet 中添加字段、标题等

在程序启动时,我们将参数分配给 TZQuery 组件,如下所示:

qryProduct.Params.ParamByName('language_id').AsInteger := 2;

其中 2 是一个演示硬编码值(在实际应用程序中,它是通过查询正在使用的 Windows 当前语言来确定的)。

现在运行应用程序:完美!

现在按 TDBNavigator 上的“刷新”。

在 TDBGrid 中,要么你得到一个讨厌的:“密钥违规”,要么是一个完全空白的 name 列。

为什么?

【问题讨论】:

    标签: sql delphi join tclientdataset


    【解决方案1】:

    解决方案如此简单,但并不那么明显。

    查看生成的刷新 SQL(通过 TZSQLMonitor)连接表,很明显参数不起作用:

    2014-01-04 11:19:38 cat: Execute, proto: mysql-5, msg: SELECT pr.product_id AS product_id,
    pr.model AS model, pd.name AS name, pr.image AS image, pr.status AS status, pr.date_added
    AS date_added, pr.date_modified AS date_modified FROM oc_product pr LEFT JOIN
    oc_product_description pd ON pr.product_id = pd.product_id AND pd.language_id = NULL
    WHERE pr.status = 1 ORDER BY pd.name
    

    参数位为:

    pd.language_id = NULL
    

    快速浏览一下 ClientDataSet 组件会发现参数 name 已从查询组件中捕获。但不是价值

    现在,我不知道这是否是 TZQuery 组件在运行时未发送参数值的问题,或者是否只是 ClientDataSet 未实现该功能但它生成的错误远未立即显现。

    当然,修复方法是在 Active 设置为 true 之前手动设置 TZQuery 和 TClientDataSet 组件中的参数值。

    【讨论】:

    • 只在ClientDataSet中设置参数就足够了。一个很好的地方是 BeforeOpen 事件。
    • Delphi 的 SQL 设计的一个大问题是首先需要为每个参数做整个费力的 param.parambyname().asinteger 等事情。一个人应该能够在单个函数调用中传递查询字符串和可变数量的值/变量。他们对新的 REST 库犯了同样的错误。
    • @UweRaabe 您有显示示例的链接吗?我找到了docwiki.embarcadero.com/RADStudio/XE5/en/…,但它似乎没有显示我在说什么。
    • @alcalde,该页面实际上显示了一个示例:FDConnection1.ExecSQL('insert into testtab values (:id, :name)', [1, 'FireDAC']);
    猜你喜欢
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    相关资源
    最近更新 更多