[Oracle] DUAL表の中身がデュアルに!? | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

テーマ:
ある日、突然、あるシステムにおいてデータが全く登録できないという状況に陥りました。

このシステムではテーブルへのレコードの INSERT 時にトリガーを起動し、その中で SEQUENCE を使ってプライマリキーを発番しているのですが、そこで軒並みエラーになっているようです。

さらに詳しく調べてみると実際に SEQUENCE を取得する SQL の実行時に以下のエラーが発生していました。

"ORA-01422 完全フェッチが要求よりも多くの行を戻しました"

このエラーは単一行が返されることを前提としている SQL に対して、複数行が返されたときに発生します。

トリガーの中で実際に SEQUENCE を取得している SQL は以下のとおりです。

SELECT XXXXXX_SEQ.NEXTVAL INTO :NEW.XXXXXX_ID FROM DUAL;

SEQUENCE から新しい値を取得しているだけですので、この SELECT 文が複数行を返すことはありえません。

しかし、INTO 句を外して、SQL を単独で実行してみると...

SQL> SELECT XXXXXX_SEQ.NEXTVAL FROM DUAL;

XXXXXX_SEQ.NEXTVAL
------------------
12345
12346
なんと、本当に複数行返ってきました。

別の SEQUENCE を確認してみましたがやはり結果は同じです。

さらに、以下の SQL でも複数行返って来ました。

SQL> SELECT SYSDATE FROM DUAL;

SYSDATE
--------
07-12-28
07-12-28
どうやら DUAL表を使った問い合わせが怪しいようです。

そこで、DUAL表を確認してみると...

SQL> SELECT * FROM DUAL;

DUMMY
-----
X
X
何と、DUAL表の中身がデュアルになっているではありませんか!

通常は1行のはずです。ありえません。

そこで、試しに1行削除してみると...無事、上記の現象は解消されました^^;


なぜ、DUAL表に行が追加されてしまったのかはよくわかりませんが、DUAL表へのINSERTの権限さえあれば、Oracle が簡単に機能不全に陥れることができるんですね。


ちなみにこの現象、発生したのは 9i ですが、10g では起こらなくなっているようです。

というか、DUAL表に行を追加しようとしても追加されません。

やはり問題があったので改修されたということなのでしょうか。