首页 文章

Oracle 11G中的LIMIT / OFFSET

提问于
浏览
7

我正在尝试更新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排序,我只想要一个特定的,因此限制1偏移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行,以相反的方式对它们进行排序,从最后四行中减去 . 此解决方案失败,因为Oracle解析器无法理解对其中一个嵌套查询中引用的最外层命令中的表的引用 .

(和以前一样的问题:MySQL to Oracle Syntax Error (Limit / Offset / Update)

挑战不仅仅是在oracle中运行带有限制和偏移的select语句,因为我已经可以通过嵌套查询来实现 . 挑战是让select语句在update语句中工作,因为即使语句在语法上是正确的,Oracle解析器也无法对它们进行解码 . 到目前为止,嵌套查询(和谷歌)已经失败了 .

还有其他人有过类似的问题吗?

1 回答

  • 0

    删除原始答案,不可行

    我认为这应该在单个SQL语句中可行,但到目前为止,对相关子查询的需求和对某种分析函数的需求的组合使我尝试的所有内容都失败了 .

    这是一个程序方法,我认为它会做你想要的:

    DECLARE
      CURSOR t IS
      SELECT LEAD(contractid,4) OVER (PARTITION BY assetid ORDER BY lasttradedate ASC) lead_contractid
        FROM table1
        FOR UPDATE;
    BEGIN
      FOR r IN t LOOP
         UPDATE table1 SET nextcontractid = r.lead_contractid
           WHERE CURRENT OF t;
      END LOOP;
    END;
    

相关问题