- PR -

oracle.data.adapterで自動生成されるSQLについて

投稿者投稿内容
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2008-09-30 21:39
あれ?
パラメータをセットしている箇所がないんじゃない?


masaさん
> エラーとは関係ありませんが、このSQLは「自動生成」されてますよね?
いや、作ってますよ。最初の投稿のコードで作っています。
おそらく、自動で生成されたものをまねて作っているのでしょう。

> where 句に各列の値が羅列されてますよね。
楽観的同時実行制御です。
確かに、LastModified でも作る方がいいと思いますけど、主キーだけで解決できる問題ではありません。
VB初心者
常連さん
会議室デビュー日: 2008/09/29
投稿数: 20
投稿日時: 2008-10-01 09:32
massさん、rainさん、ありがとうございます。

回答内容を参考に、再度調べてみます。
また、判らないことがあればレスしますので
よろしくお願いします。
VB初心者
常連さん
会議室デビュー日: 2008/09/29
投稿数: 20
投稿日時: 2008-10-01 10:37
レスを頂いた皆様、ありがとう御座いました。

プレースホルダの名前の付け方を変更してみたところ、
正常に動作しました。
その他、ご指摘頂いた事については、再考してみたいと
思います。
ありがとう御座いました。
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-10-01 11:01
本題とは関係ないかもしれませんが、すみません。

引用:

masaさんの書き込み (2008-09-30 19:49) より:

SQLServer の場合、こういうコマンドでトランザクションがらみの内部エラーが発生することがあります。内部でもみ消されるので厄介な現象です。
Oracle では試したことはありませんが、危険かも。



引用:

Jittaさんの書き込み (2008-09-30 21:39) より:

> where 句に各列の値が羅列されてますよね。
楽観的同時実行制御です。
確かに、LastModified でも作る方がいいと思いますけど、主キーだけで解決できる問題ではありません。



お二方の述べられている問題というのがよくわからなかったのですが、よろしければもうちょっと詳しく教えてください。
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2008-10-01 13:24
.NET1.1 + SQLServer2005 で発生しました。プロバイダは SqlDb だったと思います。
私はそのプロジェクトの担当ではなく一時的に調査に参加したため曖昧な部分がありました。
当時の調査資料を見てみたところ、少し主旨が違っていました。ごめんなさい。


発生した現象はつぎのようなものです。

・主キーのないテーブルに複数件のレコードを登録する処理で、
処理後にトランザクションをコミットまたはロールバックしようとすると
「トランザクションは開始されていません」となりました。

・データベース処理中には例外は発生しませんでした。

・データベースには複数件のうち後半の数件だけが登録されていました。
先頭から数件はロールバックされたと考えられます。

・登録処理はデータアダプタを利用していました。
アダプタ及び登録コマンドはウィザードを使って作成しました。
その際「更新後の再取得を行わない」のチェックを外しました。
データセットに登録された後のデータを再投入するためです。


System.Data.dll の中を見たりといろいろ検証した結果、
次のような結論に至りました。

・更新後の再取得を行う場合、
更新コマンドの commandText には次のような二つのSQL文がセットされます。
主キーがあれば select 文に主キーによる where 句が追記されるのですが、
主キーがないと何も条件が付きません。全件取得となります。

insert into テーブル values ( 値1, 値2, 値3 );
select 列1, 列2, 列3 from テーブル;

・データアダプタの更新処理では、対象レコードの数だけ更新処理を繰り返します。
コマンドには insert と select が記述されていますから、取得も繰り返されることになります。(←この一文を追記しました)
その途中でエラーが起きるようですが、例外は発生しません。
プロバイダで発生しているのか、データベースで発生しているのかはわかりませんでした。

・エラーが起きると、データベース側ではロールバックが行われます。
ここでトランザクションは終わります。以降は即時更新となります。
アプリケーションでコミット/ロールバックをしようとすると、
「トランザクションは開始されていません」となります。

・更新後の再取得を行わない場合は、この現象は起きませんでした。
テーブルに主キーが定義されている場合もこの現象は起きませんでした。
以上から、テーブルの全レコードが繰り返し取得されることによって引き起こされるようです。
oracle では登録コマンドの中に select 文を書けないような気もしますし、
SQLServer だけの話かもしれません。


マイクロソフトからも現象を認める回答を得られたと聞いてはいますが、
私の手元にはありません。
ググってみましたが、該当する記事はありませんでした。


なお、VisualStudio2005 のウィザードでは、
主キーのないテーブルの場合には「更新後の再取得を行わない」のチェックが
on のままで使用不可になり、触れなくなっていたりもします。




「楽観的同時実行制御」は排他制御の話で、主キーの有無とは関係ないと思います。
"更新スタンプ"のような列によってレコードに対して論理的な排他制御をかけるかどうかということです。

主キーを張れるなら張ったほうがよいと思います。
将来的に列が増えるたびに where 句を追加していかなくてはならなくなりますし、
パフォーマンス面でも不利です。


[ メッセージ編集済み 編集者: masa 編集日時 2008-10-01 13:30 ]
VB初心者
常連さん
会議室デビュー日: 2008/09/29
投稿数: 20
投稿日時: 2008-10-01 15:01
色々とアドバイスを頂き、ありがとう御座います。
現在はサンプルDBを仕様して、動作の確認をしている
のですが、最終的には主キーを設定して行います。
基本的には無線通信端末からの要求に対して、oracle
のテーブルを1件単位でアクセスする仕様になります。
(複数件の同時処理は発生させない)
とりあえず、動作確認は出来ましたので、これから
本格的に開発を進める予定です。
ありがとう御座いました。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2008-10-01 22:53
引用:

rainさんの書き込み (2008-10-01 11:01) より:
お二方の述べられている問題というのがよくわからなかったのですが、よろしければもうちょっと詳しく教えてください。


 ああ、済みません。
「主キーを設定したら、WHERE 句に各列の値を並べなくても良い」と書かれているように思えたので、「それは違うんじゃない?」という指摘でした。

 「主キーを設定したからといって、各列の値を検査しなくても良い、というわけではない」に改めます。

スキルアップ/キャリアアップ(JOB@IT)