使用用户定义函数作为表的 DB2 查询结构
Posted
技术标签:
【中文标题】使用用户定义函数作为表的 DB2 查询结构【英文标题】:DB2 Query Structure Using User-Defined Function as a Table 【发布时间】:2011-09-01 18:36:44 【问题描述】:我对 DB2 有点陌生,在开发查询时遇到了麻烦。我创建了一个用户定义的函数,它返回一个数据表,然后我想在更大的 select 语句中加入并从中选择。我正在处理一个敏感的数据库,所以下面的查询并不是我真正正在运行的,但它几乎完全一样(没有其他 10 个连接,我必须做大声笑)。
select
A.customerId,
A.firstname,
A.lastname,
B.orderId,
B.orderDate,
F.currentLocationDate,
F.currentLocation
from
customer A
INNER JOIN order B
on A.customerId = B.customerId
INNER JOIN table(getShippingHistory(B.customerId)) as F
on B.orderId = F.orderId
where B.orderId = 35
如果我在没有 where 子句(或其他不检查 ID 的 where 子句)的情况下运行此查询,这将非常有用。当我包含 where 子句时,我收到以下错误:
准备期间出错 58004(-901)[IBM][CLI 驱动程序][DB2/LINUXX8664] SQL0901N 由于系统不严重,SQL 语句失败 错误。可以处理后续的 SQL 语句。 (原因“糟糕的计划; 找到未解析的 QNC”。) SQLSTATE=58004
我已将问题归结为我正在使用参数 (B.customerId) 的连接条件之一。我通过将 B.customerId 替换为有效的 customerId 来验证这一事实,并且查询效果很好。问题是,调用此查询时我不知道 customerId。我只知道 orderId(在这个例子中)。
关于如何重组它以便我只能拨打 1 次电话以获取所有信息的任何想法?我知道计划是在调用函数之前 customerId 没有得到解决的问题。
【问题讨论】:
【参考方案1】:所以如果我理解正确的话,函数 getShippingHistory(customerId) 返回一个表。
如果您使用单个客户 ID 调用它,则该表将加入到您的查询中,完全没有问题。
但是按照上面编写的查询方式,您要求 db2 为查询返回的每一行调用该函数(即每个 b.customerId 与您的联接和 where 条件匹配)。
所以我不确定您期望什么行为,因为您要求的是查询中每一行的表,而 db2(我也不知道)可以弄清楚结果应该是什么样子.
因此,在重组查询方面,请考虑在涉及多个客户 ID 时如何更改 getShippingHistory 逻辑。
【讨论】:
“如果您使用单个客户 ID 调用它,那么该表将在您的查询中加入上面的查询完全没有问题”实际上相反。如果我使用客户 ID,它会失败。返回所有 ID 时它工作正常。 哦,您在问题中所说的是“我已经通过将 B.customerId 替换为有效的 customerId 来验证这一事实,并且查询效果很好。”无论如何,我很高兴你解决了它。【参考方案2】:我发现最好的解决方案(给定当前的查询结构)是使用 LEFT 连接而不是 INNER 连接,以便强制连接的 LEFT 部分发生,这将在 customerId 获取时将其解析为一个值到函数调用。
select
A.customerId,
A.firstname,
A.lastname,
B.orderId,
B.orderDate,
F.currentLocationDate,
F.currentLocation
from
customer A
INNER JOIN order B
on A.customerId = B.customerId
LEFT JOIN table(getShippingHistory(B.customerId)) as F
on B.orderId = F.orderId
where B.orderId = 35
【讨论】:
以上是关于使用用户定义函数作为表的 DB2 查询结构的主要内容,如果未能解决你的问题,请参考以下文章