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

使用用户定义函数作为表的DB2查询结构,db2,user-defined-functions,Db2,User Defined Functions,我对DB2有点陌生,在开发查询时遇到困难。我创建了一个用户定义的函数,它返回一个数据表,然后我想在更大的select语句中加入并从中进行选择。我正在处理一个敏感的数据库,所以下面的查询不是我真正正在运行的,但它几乎和它一模一样(没有其他10个连接,我必须做lol) 如果我在不使用where子句(或其他不检查ID的where子句)的情况下运行此查询,这将非常有用。当我包含where子句时,我得到以下错误: 准备58004(-901)[IBM][CLI驱动程序][DB2/LINUXX8664]时出错

我对DB2有点陌生,在开发查询时遇到困难。我创建了一个用户定义的函数,它返回一个数据表,然后我想在更大的select语句中加入并从中进行选择。我正在处理一个敏感的数据库,所以下面的查询不是我真正正在运行的,但它几乎和它一模一样(没有其他10个连接,我必须做lol)

如果我在不使用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没有得到解决。

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


若您使用单个客户Id调用它,那个么在上面的查询中加入该表并没有任何问题

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

因此,我不确定您期望的是什么行为,因为您要求的是查询中每一行的返回表,db2(或我)可以确定结果应该是什么样子

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

我找到了最佳解决方案(考虑到当前的查询结构)是使用左连接而不是内部连接,以强制连接的左部分发生,这将在到达函数调用时将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

“如果您使用一个客户Id调用它,那么在上面的查询中加入该表一点问题都没有”事实上,情况正好相反。如果我使用客户ID,它会失败。返回所有ID时,它可以正常工作。哦,你在问题中说的是“我已经用有效的customerId替换了B.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