【发布时间】:2011-11-11 17:12:01
【问题描述】:
我正在尝试更新 Oracle 中的表,但遇到了一些困难。我正在从 MySQL 移植我的代码,而 Oracle 不支持 MySQL 允许的一些命令。
这是 MySQL 代码:
update table1 t1 set c5 = (select ContractID from table2 t2 where t1.assetid =
t2.assetid and t1.lastdate >= t2.lastdate and t1.firstdate= t2.firstdate
order by lastdate asc limit 1 offset 4);
子查询返回一个 ContractIDS 列表,按 lastdate 排序,我只想要一个特定的,因此是 limit 1 offset X 命令。
问题如下。 Oracle 不支持“limit”或“offset”命令。使用 rownum 和嵌套查询可以解决限制问题,但 Oracle 11G 解析器不喜欢在 UPDATE 命令中使用它们。
在更新命令中需要限制而不是偏移量之前,我遇到了类似的问题。在这里解决了:MySQL to Oracle Syntax Error (Limit / Offset / Update)
Florin Ghita 使用分析函数找到了一种解决方法。
update table1 alf
set nextcontractid =
(SELECT min(contractid) keep (dense_rank first order by lasttradedate asc)
FROM table1copy alf2
WHERE alf2.assetid = alf.assetid
AND alf2.lasttradedate > alf.lasttradedate
)
where alf.complete = 0
此解决方法允许我获取顶部或底部条目(通过在 dense_rank 命令中使用 asc 或 desc),但如果我想要第二行或第三行,我无法找到 offset 命令的代理。
我尝试过的另一个解决方案是使用嵌套查询。第一个使用 rownum 命令获取前 5 行,以相反的方式对它们进行排序,最后四行减去 MINUS。此解决方案失败,因为 Oracle 解析器不理解对嵌套查询中引用的最外层命令中的表的引用。
(和我之前遇到的问题一样:MySQL to Oracle Syntax Error (Limit / Offset / Update))
挑战不仅仅是在 oracle 中运行带有限制和偏移量的 select 语句,因为我已经可以通过嵌套查询来做到这一点。挑战在于让 select 语句在更新语句中工作,因为即使该语句在语法上是正确的,Oracle 解析器也无法解码它们。到目前为止,嵌套查询(和 Google)都让我失望了。
有没有其他人遇到过类似的问题?
【问题讨论】:
-
如果你升级到 12c,你也许可以做类似
update table1 t1 set c5 = (select ContractID from table2 t2 where t1.assetid = t2.assetid and t1.lastdate >= t2.lastdate and t1.firstdate= t2.firstdate order by lastdate asc offset 4 fetch next 1 row only); -
相关的,如果你有 Oracle 12cR1(或更高版本)可能有用:stackoverflow.com/a/26051830/1461424
标签: mysql sql oracle oracle11g offset