【问题标题】:IBM DB2 9.7 common table expression with update带有更新的 IBM DB2 9.7 公用表表达式
【发布时间】:2012-11-14 23:41:49
【问题描述】:

我正在尝试:

  1. 选择一行并将其命名为 CTE
  2. 更新该表 CTE 的一些列

我正在使用公用表表达式来实现它,但我无法让它工作。

Begin
With CTE AS
(select * from MyTable where Column1 is null order by Column2 desc
(Update CTE
Set Column3= 1, Column4 = 1, Column5 = 1))
Commit;

我已尝试遵循 DB2 规范,但仍有问题:)

【问题讨论】:

  • 这(可能)取决于您的 DB2 版本(和平台),应该包括在内。另外,请注意,除非您有某种依赖于在 CTE 中的排序的函数(例如,FETCH FIRST 1 ROW ONLY),否则ORDER BY 将在查询的其余部分很大程度上被忽略,并且可能会被优化器删除。

标签: sql db2 common-table-expression


【解决方案1】:

通常,CTE 的语法看起来更像这样。注意括号。

With CTE AS
(
  select * from MyTable where Column1 is null order by Column2 desc
)
Update CTE
Set Column3= 1, Column4 = 1, Column5 = 1;

this documentation 建议您不能将 UPDATE 语句与 CTE 一起使用。

您可以在任何可以有的地方定义一个公用表表达式 全选语句。例如,您可以包含一个公用表 SELECT、INSERT、SELECT INTO 或 CREATE VIEW 语句中的表达式。


可能的解决方法

如果 CTE 不可更新,只需删除 CTE,然后编写 UPDATE 语句。您在这里根本不需要 ORDER BY。这看起来像一个等效的 UPDATE 语句。

update MyTable
set ...
where Column1 is null

【讨论】:

  • 关于您的回答,您的最终结论是 CTE 无法进行更新吗?如果是这样,有什么解决方法的想法吗?
  • 不,我没有断定 UPDATE 是不可能的,因为我认为不同版本的 DB2 有不同的特性集。不仅版本号不同,而且我认为大型机版本有时与中端版本和 i386 版本略有不同。 (我可能错了。)但是由于括号,您发布的声明无论如何都不会起作用。测试是否可以插入到 CTE 中。 (INSERT 记录在案,至少在我链接到的页面上。)如果你可以插入,但不能更新,那么,这就是你的答案。
  • 看起来 UPDATE 是不可能的......该死的,有很多可以用 T-SQL 但不能用 PL-SQL 完成 :)
  • 对不起,我忘了说我只为选择获取前 1 行。因此,Column2 的顺序...
  • 不,您正在获取 Column1 中所有具有 NULL 的行。你只是希望忽略很多你正在获取的行。 (您的 UPDATE 语句将尊重 WHERE 子句,但不会尊重希望。)有更好的方法来更新单行。
【解决方案2】:

这个怎么样

UPDATE (
  SELECT * FROM MYTABLE WHERE COLUMN1 IS NULL ORDER BY COLUMN2 DESC
  FETCH FIRST 1 ROW ONLY
)
SET COLUMN3= 1, COLUMN4 = 1, COLUMN5 = 1;

或者如果你想要更多的灵活性,也许我的回答是How to Update Multiple Queries in optimized way in DB2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    相关资源
    最近更新 更多