【问题标题】:DB2 Function Loop?DB2 函数循环?
【发布时间】:2014-06-05 21:23:47
【问题描述】:

我们称之为 foo

我会这样称呼它:

Select * From TABLE (schema.foo("aString"))

它将返回与该用户名相关的所有项目的字符串。

EG

Select * From TABLE (schema.foo("apple")) = 

apple
-----
fruit
red
delicious

我想要做的是遍历一个列表,并针对该列表中的每一行运行该过程。

我正在尝试运行的内容:

Select * from schema.fruits where name in (Select * From TABLE (schema.foo(fruits.name))

但是它没有给我正确的输出。我想要的是以下内容:

apple  | fruit
apple  | red
apple  | delicious
orange | fruit
orange | orange
orange | also delicious

有什么想法吗?

【问题讨论】:

  • 你能附上你的SP代码吗?

标签: sql stored-procedures db2


【解决方案1】:

您的查询基本上是在说以下内容:

嘿,对于fruits中的每个name,获取函数foo()的输出,然后如果name在输出中,则仅从fruits返回数据。

你看到这里的两个问题了吗?

  1. 您的查询要求 foo 再次输出输入(不太可能,并且在某些情况下会出现问题)。
  2. IN 子句比较的数据不能是SELECTed - 您会得到布尔 (true/false) 结果。

现在,问题 2 可以通过切换到 JOIN + 子查询轻松解决:

SELECT ...
FROM Schema.Fruits
JOIN (SELECT ...
      FROM TABLE (Foo(Fruits.name))) FooOut(descr)
ON ....

...因为函数的输出现在不直接用于比较,而是在主查询中显示为其他数据/另一个表。

请注意,我对relevant portion of the documentation 的阅读表明整个子查询可以简化为:

JOIN TABLE (Foo(Fruits.name)) FooOut(descr)
ON ....

问题是问题 1,以及 RDBMS 的工作原理。

SQL 作为一种语言被设计用于操作集合,即匹配记录的组。这有很多原因,但问题是大多数人并没有真正考虑数学集合,因为这不是他们习惯的东西。当您 (INNER) JOIN 一张表到另一张表时,您是在说“给我获取 table_a 中的所有行,然后乘以 table_b 中的所有匹配行(包括 a 中的行)。

问题是我不确定由于使用该函数会生成哪些集合。但是,我认为您应该能够摆脱这样的困境:

SELECT Fruits.name, FooOut.descr 
FROM Schema.Fruits
CROSS JOIN TABLE (Foo(Fruits.name)) FooOut(descr)

(INNER) JOINCROSS JOIN 之间的区别在于,CROSS JOIN 不允许关联(ON 子句) - table_a 中的所有行将乘以 table_b 中的所有行.这是有趣的部分 - 在这种情况下,table_b(函数生成的表)中的行应该只存在table_a中的相关行(匹配的Schema.Fruits行)。

如果这不起作用,您可能需要更改 Foo(...) 的输出以在结果表中包含一个额外的列,该列仅由输入 Fruits.name 组成。

【讨论】:

    【解决方案2】:

    不确定我是否理解问题,但我的猜测是:

    select x.* 
    from schema.fruits as f 
    cross join TABLE (schema.foo(f.name)) as x 
    

    【讨论】:

      猜你喜欢
      • 2018-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-13
      • 2019-08-28
      • 2021-12-03
      • 2016-01-04
      相关资源
      最近更新 更多