Mystery Parametric SQL Query with join + TClientDataSet空白字段

时间:2014-01-04 12:01:01

标签: sql delphi join tclientdataset

有时甚至显而易见的事情似乎都出错了。在处理SQL组件时有很多显而易见的事情可以肯定是错误的,当它们只是整个SQLQuery =>的环时更是如此。提供者=> 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列。

为什么?

1 个答案:

答案 0 :(得分: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组件中手动设置参数值。