2

Oracle (挿入/更新/削除時) に row_num 分析関数を使用して行番号を割り当てるように強制する方法はありますか?

私が何を意味するかを説明するためのコード例:

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

上記のクエリは、パーティション句に基づいて行番号を割り当てます。

今、クエリを実行して、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
....

すべてまたは一部の値を挿入できます-外側の選択パーツから不要なものを削除します。

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

この方法の問題点の 1 つは、一度に 1 つのプロセスしかテーブルを変更できないこと、または partition-by 句で定義されたテーブルのサブセットしか変更できないことです。これは、テーブルを変更する複数のセッションが、コミットされるまで、他のセッションが行った変更を見ることができないためです。

ただし、ロックによってこの制限に対処できる場合、これをコーディングできない理由はありません。値が常に増加する挿入のみは比較的単純ですが、他の状況はもちろんより複雑であり、私が考えることができる自動のものはありません。ただし、詳細なアドバイスやコーディング サンプルを提供することはためらいます。

于 2012-12-28T15:38:54.687 に答える
0

PK_IDを作成するつもりですか?その場合は、代わりにSEQUENCEを使用してください。それはあなたのためにその仕事をします。

CREATESEQUENCE-Oracleドキュメント

于 2012-12-28T20:03:41.810 に答える