- PR -

データ取得時に「実行時例外がスロー」が発生

1
投稿者投稿内容
おかぴ
会議室デビュー日: 2003/12/19
投稿数: 7
投稿日時: 2003-12-19 10:10
みなさん。始めまして。おかぴと申します。
早速ですが表題の件について質問させて貰います。

まずは環境ですが。
Win2K VB.NET 
ORACLE8.1.6(本番では9iを使用します)を使用しています。

マシン(A)では問題なく動作していたロジックが
マシン(B)にて動作させたところ下記のようなエラーが起きて
しまいました。

実行時例外がスローされました : System.InvalidOperationException - 行および列にデータが存在しません。

エラー箇所は下記のサンプルソースにて明示してあります。
原因がつかめない為、どなたか教えて頂けないでしょうか。

なお、マシン(A)のOLEDBは8.1.6で
マシン(B)のOLEDBは8.1.7となっています。

以下は、そのサンプルソースとなります。

Module Param1
Public OleCn As New OleDb.OleDbConnection
Public OleCmd As OleDb.OleDbCommand
Public SQL As String
Public DATA As OleDb.OleDbDataReader
End Module

Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
OleCn.ConnectionString = _
"Provider=OraOLEDB.Oracle.1;" & _
"Persist Security Info=False;" & _
"User ID = user;" & _
"Password = pass;" & _
"Data Source= DB"
OleCn.Open()

End Sub

Private Sub Correct_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
SQL = ""
SQL = "SELECT * from A "
SQL = SQL & "WHERE CODE_H = " & TextBox2.Text & " AND "
SQL = SQL & "CODE_E = " & TextBox3.Text

'SQLの発行
OleCmd = New OleDb.OleDbCommand(SQL, OleCn)
DATA = OleCmd.ExecuteReader()
Do While (DATA.Read())
TRIM_WORK = DATA.GetString(3) ←エラー箇所
TextBox4.Text = TRIM_WORK.TrimEnd
Loop
End Sub
DATA.close

長文となり失礼致します。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-12-19 13:19
 SQL文で返される列の数はいくつですか?3列返ってくるなら、GetString(2)です。インデックスは0から始まります。

 または、GetStringではヌルのデータは取得できないので、事前にDbNull.Valueと比較するか、IsDbNullで検査します。
#「行および列にデータが存在しません。」だから、こっちっぽいなぁ


 また、TextBox2に、「CODE_H;--」と入力したら、どうなると思いますか?「CODE_H列に文字列『CODE_H;--』は無いから何も返ってこない」と思いますか?全行返ってきますよ。なぜかは、「;」や「--」が、SQLでどういう意味を持っているか、調べてください。
#TextBoxのOnKey系イベントで数字以外は…というのは、
#ペーストされると×です
#OnChageイベントか、代入直前に検査しているなら○

 ではどうしらたらいいかは、OleDbParameterを調べてください。


 それから、データベースの開きっぱなしも、良くないですね。この例だと、WindowsアプリかWebアプリかわかりませんが、Webアプリであれば短期間にアクセスが集中すると、すぐにパンクしますよ。開いたものは必ず閉じてください。
おかぴ
会議室デビュー日: 2003/12/19
投稿数: 7
投稿日時: 2003-12-19 14:36
Jittaさん こんにちは。

すみません。レスを頂いてから説明が不足していたことに気づきました。

まずDBのレイアウトは以下になります。
FIL1        NOT NULL CHAR(5)
GM_CODE_H     NOT NULL NUMBER(2)
GM_CODE_E     NOT NULL NUMBER(9)
GM_MEISYO     NOT NULL CHAR(44)
GM_SEIGYO     NOT NULL CHAR(40)
GM_YOBI      NOT NULL CHAR(20)
GM_KOUSIN_YMD   NOT NULL NUMBER(
で、その中の”GM_MEISYO”を取得しようとしている為、GetString(3)としていました。
NULLは禁止しているレイアウトとなっています。
また条件式に代入するTextBoxにはNUMチェックをかけています。

とりあえず自己解決できました。ただ数点納得がいかない部分が残ります。
1 なぜAで動作していたものがBでは動作しなかったか。
2 半角SPACEは文字列として認識できないのか。
  半角SPACEを文字列として認識するにはマシンに依存する何かが存在するのか?
3 条件式でレコードを特定できているにも関らず他のレコードに
  半角SPACEが入力されている場合、なぜ異常終了となるのか


>それから、データベースの開きっぱなしも、良くないですね。この例だと、Windowsアプリか
>Webアプリかわかりませんが、Webアプリであれば短期間にアクセスが集中すると、すぐにパ
>ンクしますよ。開いたものは必ず閉じてください。
セッションクローズの部分はフォーム終了時に行っています。
Webアプリの場合だと基本的なつくりは
SELECT等を行う直前でセッションのOPEN・CLOSEを行うべき!という
認識でよろしいですか?

[ メッセージ編集済み 編集者: おかぴ 編集日時 2003-12-19 14:38 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-12-19 15:03
 OLEDB8.1.6とかOLEDB8.1.7とかって、ODBCドライバのバージョンのことですか?System.Data.OleDbって、固定というか、Frameworkのバージョンと一緒のはず、、、とかって思ってました^^;

 え〜と、私も理由はよくわからないのですが、文字列型の桁数は、16の倍数にしておく方がよいそうです。Oracleのコアな部分を設計開発している友人を持つ同僚の言葉なので、鵜呑みにしています。
#16,32,64,128...ではなく、16,32,48,64,80...念のため


> Webアプリの場合だと基本的なつくりは
> SELECT等を行う直前でセッションのOPEN・CLOSEを行うべき!という
> 認識でよろしいですか?

 Webアプリに限らず、外部リソースは「使用直前に確保、使用直後に解放」が基本です。
 Windowsアプリのようですが、マシンA、マシンBと言うことは、Server/Clientで、クライアントは複数台あるのですね。では、クライアントが50台あって、50の端末が一斉にアプリケーションを起動したら、どうなりますか?

あ…Oracleのライセンス体系が変わってる。昔って、「接続数」でライセンスを数えていませんでしたっけ?つまり、「10接続」分のライセンスしか買ってなかったら、「同時に10人」しか使えませんよね、ってことが言いたかったのですが。。。
おかぴ
会議室デビュー日: 2003/12/19
投稿数: 7
投稿日時: 2003-12-19 15:17
>Webアプリに限らず、外部リソースは「使用直前に確保、使用直後に解放」が基本です。
>Windowsアプリのようですが、マシンA、マシンBと言うことは、Server/Clientで、クライ>アントは複数台あるのですね。では、クライアントが50台あって、50の端末が一斉にアプ>リケーションを起動したら、どうなりますか?

いままでの仕事ではオラクルへのセッションはメニュー起動時にかけて
終了時にセッションを切るという形式でしたので。。(汗)
それこそ端末台数は50台以上・・・ なんて状況でも・・・ 

さきほどのいくつかの疑問点は新しくスレッドをたてて聞いてみます。
1

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