2

是否存在强制 Oracle(在插入/更新/删除时)使用 row_num 分析函数来分配行号的方法,以后可以通过简单地调用 where rownumber = X 来检索?

示例代码来说明我的意思:

select foo,bar,baz  
    row_number() over (partition by bang order by some_date desc) rn  
from my_table

上述查询将根据分区子句分配行号。

现在,当我查询并且我想要 where rownumber = XI 可以这样做时:

select foo,bar,baz  
from my_table  
where rownumber=1

这样做的原因是为了避免查询开销并将其推回到在系统中发生频率要低得多的 DDL 语句中。所以我的问题又来了,这样的事情可能吗?

评论

每个新的插入/更新/删除都可能会更新表的每一行……这可能需要大量的日志记录(和锁定)。如果您的数据本质上是静态的,则在每次加载或更新时重新生成行号。

如果我们删除更新/删除的约束,我不相信这种推理仍然存在,尤其是在时间对象驱动它的情况下。

4

3 回答 3

1
 SELECT ename, deptno, rownum, rno
  FROM (SELECT ename, deptno, row_number() OVER (Order By deptno) rno
           FROM scott.emp
        ORDER BY deptno)
 /
ENAME          DEPTNO     ROWNUM        RNO
---------- ---------- ---------- ----------
CLARK              10          1          1
KING               10          2          2
MILLER             10          3          3
JONES              20          4          4
FORD               20          5          5
ADAMS              20          6          6
....

您可以插入全部或部分值 - 从外部 Select 部分中删除不需要的值:

INSERT INTO emp_test2
(
SELECT ename, deptno, rownum row_num, rno
  FROM (SELECT ename, deptno, row_number() OVER (Order By deptno) rno
       FROM scott.emp
    ORDER BY deptno)
);
于 2012-12-28T19:13:18.683 回答
1

一种方法的一个问题是,您一次只能有一个进程修改表,或者partition-by 子句定义的表的一个子集。这是因为修改表的多个会话在提交之前无法看到其他人所做的更改。

但是,如果您可以通过锁定来应对此限制,那么就没有理由无法对其进行编码。值总是递增的仅插入会相对简单,但其他情况当然会更复杂,而且我能想到的都不会是自动的。不过,我会犹豫提供详细的建议或编码示例。

于 2012-12-28T15:38:54.687 回答
0

您是否打算创建一个 PK_ID?如果是这样,请改用 SEQUENCE。它会为你完成这项工作。

创建序列 - Oracle 文档

于 2012-12-28T20:03:41.810 回答