Skip to Main Content

Japanese

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

バインド変数を使用したINSERTでORA-00001(一意制約違反)

870553Jun 22 2011 — edited Jun 26 2011
タイトル修正しました。元タイトル:プログラムからのINSERTでORA-00001(一意制約違反)
---------------------------------------------

お世話になります。
簡単なプログラムを作っていて、おかしい事象が出ており、識者の方にお聞きしたく思います。

環境:
 プログラム側 VB.NET(2010)+ODP.NET(DB付属のものを参照設定して利用。)

DB側:
 Oracle 11g R2 Standard Edition One on Windows Server 2008 R2

テーブル: Test
 memo_id as varchar2(10),
memo_no as number,
memo_text as varchar2(2000),
primary key (memo_id, memo_no)


プログラム側で発行しているSQLは、memo_idごとにmemo_noを発行し、テキストを登録する、という内容です。

INSERT INTO Test ( memo_id, memo_no, memo_text ) VALUES (
:memoId
,COALESCE((SELECT MAX(memo_no) FROM TEST WHERE memo_id=:memoId), 0) + 1
,:memoText
)

このSQLで以下のようにデータ登録されるものと思っていました。(memo_id ごとに、枝番を発番するイメージ)

1件目の時:
 パラメータ --> memoId='id-00001', memoText='メモ内容:00001-1'
 期待したデータ --> ('id-00001', 1, 'メモ内容:00001-1')

2件目の時:
 パラメータ --> memoId='id-00001', memoText='メモ内容:00001-2'
 期待したデータ -->  ('id-00001', 2, 'メモ内容:00001-2')

3件目の時:
 パラメータ --> memoId='id-00002', memoText='メモ内容:00002-1'
 期待したデータ -->  ('id-00002', 1, 'メモ内容:00002-1')

4件目の時:
 パラメータ --> memoId='id-00001', memoText='メモ内容:00001-3'
 期待したデータ -->  ('id-00001', 3, 'メモ内容:00001-3)

5件目の時:
 パラメータ --> memoId='id-00002', memoText='メモ内容:00002-2'
 期待したデータ -->  ('id-00002', 2, 'メモ内容:00002-2')


他の環境、他のプログラムではこういうSQLを多用していたので、今回も問題ないだろうと思っていたのですが、
うまくいかずにORA-00001(一意制約違反)のエラーとなってしまいました。


テーブルの主キーを外して試してみると、実際に登録された内容は下のようになりました。

1件目の時:
 パラメータ --> memoId='id-00001', memoText='メモ内容:00001-1'
 実際のデータ --> ('id-00001', 1, 'メモ内容:00001-1')

2件目の時:
 パラメータ --> memoId='id-00001', memoText='メモ内容:00001-2'
 実際のデータ -->  ('id-00001', 1, 'メモ内容:00001-2')

3件目の時:
 パラメータ --> memoId='id-00002', memoText='メモ内容:00002-1'
 実際のデータ -->  ('id-00002', 1, 'メモ内容:00002-1')

4件目の時:
 パラメータ --> memoId='id-00001', memoText='メモ内容:00001-3'
 実際のデータ -->  ('id-00001', 1, 'メモ内容:00001-3)

5件目の時:
 パラメータ --> memoId='id-00002', memoText='メモ内容:00002-2'
 実際のデータ -->  ('id-00002', 1, 'メモ内容:00002-2')


SQLを下のようにいじって、memo_idごとに発番している部分を固定化すると1,2,3,4,5 と枝番がカウントアップしていくのですが、
それだとシーケンスを使っているのと同じですし・・・

INSERT INTO Test ( memo_id, memo_no, memo_text ) VALUES (
:memoId
,COALESCE((SELECT MAX(memo_no) FROM TEST WHERE memo_id='id-00001'), 0) + 1
,:memoText
)


ちなみに、SQL*Plus で各パラメータを固定して実行すると、意図通りに期待したデータが入ります。

何とか評価順を変えて、意図通りのデータが入れられるようにしたいのですが、SQLを少しいじってみてもうまくいきませんでした。

なんとか評価順を変えて、枝番を発番しながらINSERTできる方法はありますでしょうか?


以上です。よろしくお願いします。

Edited by: user8848963 on 2011/06/23 1:50
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jul 24 2011
Added on Jun 22 2011
3 comments
5,434 views