2011-06-20 11 views
0

2つのvarchar2列を持つ表があります。この列の主キーを作成するために、既存のテーブルに新しい数値列を追加しました。この表には3つの列が含まれています。私は次のように匿名ブロックを使用しようとしました:
declare
cnt number;
begin
select nvl(count(*),0) into cnt from sometable;
for i in 1..cnt
loop
update sometable set id=i where i=rownum;
end loop;
end;

この匿名ブロックを使用すると、このテーブルが突然更新されます。
私のソリューションは、次のステートメントを使用していた:
create table sometablecopy as select row_number() over(order by sometable.col1) as id, sometable.* from sometable;
それでも私は骨董品がなぜ無名ブロックの生産がROWNUMの疑似列の助けを借りて、主キーの値を期待しないのですか?それはrownum関連の問題でなければなりません。新しい列をOracle表に追加した後の主キー値の生成

+0

予期しない結果は何ですか? – StevieG

+0

結果が返されたときにRownumが割り当てられます。結果として、少なくとも1つの行がある場合、最初のものは1に等しいrownumを持たなければならないので、 'SELECT WHERE rownum <1'を実行することは決してできません。 – Benoit

+0

StevieG:すべての行は、最初の行最初の行は番号1を持ち、他の行はcnt変数を持ちます。 – reforrer

答えて

1

ROWNUMは擬似列です。選択から戻されるときに行に割り当てられます。だから、あなたが言うことはできません "選択* my_table where rownum = 42" rownum = 42との行はまだ定義されていないので、それはあなたの選択と述語によって異なります(と "select * from my_table where rownum = 1 "最初の行ではなく、1つの行が返されます)。

これは、テーブル全体を更新するのに十分なロールバックがあることを前提としています。

希望に役立ちます。

+0

素晴らしい作品と私​​はそれを使用します!ありがとう! – reforrer

+0

Peter Langは、これに代わって非常に単純な解決策を提案しています。 UPDATE文を複雑にする必要があるときは、カーソルとROWIDを使用する方が効率的です。 – reforrer

1

ROWNUMのように使用することはできません(ROWNUM in SQLを参照)。

あなたが行っている可能性はこれです:

UPDATE sometable SET id = ROWNUM; 
+0

実際にそれを構成するのは簡単すぎますが、この作業の目的上は受け入れられます:) – reforrer

+0

@reforrer:あなたが何を意味するかわかりません。どのように単純すぎることができますか? –

関連する問題