使用用户定义函数作为表的DB2查询结构

时间:2011-09-01 18:36:45

标签: db2 user-defined-functions

我对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)。我已经通过用有效的customerId替换B.customerId来验证这一事实,并且查询效果很好。问题是,我在调用此查询时不知道customerId。我只知道orderId(在这个例子中)。

有关如何重组这一点的任何想法,所以我只能打一个电话来获取所有信息?我知道计划是问题b / c在调用函数之前,customerId没有得到解决。

2 个答案:

答案 0 :(得分:0)

因此,如果我理解正确,函数getShippingHistory(customerId)将返回一个表。

如果您使用单个客户ID调用该表,则表格会在您的查询中加入上面没有任何问题。

但是你上面写的查询方式,你要求db2为查询返回的每一行调用函数(即每个与你的连接和条件匹配的b.customerId)。

所以我不确定你期望的是什么行为,因为你要求的是查询中每一行的表格,db2(也是我)可以弄清楚结果应该是什么样的

因此,在重构查询方面,请考虑在涉及多个客户ID时如何更改getShippingHistory逻辑。

答案 1 :(得分:0)

我发现最好的解决方案(给定当前的查询结构)是使用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