DOBON.NET DOBON.NETプログラミング掲示板過去ログ

OracleDataReaderで2つの結果を取得

環境/言語:[XP/VB.NET/.NET Framework1.1/ORACLE9i]
分類:[.NET]


hiroと申します。
OracleDataReaderに2つの結果を持たせて、NextResultで結果を使いまわしたいのですが、以下のようなSQLを実行するとエラーが発生します。

cmd.CommandText = " SELECT A, B FROM TEST ORDER BY C;"
cmd.CommandText = cmd.CommandText & "SELECT D FROM TEST2 ORDER BY E"

発生するエラーは
[System.Data.OracleClient.OracleException' のハンドルされていない例外が system.data.oracleclient.dll で発生しました。]
です。

OracleDataReaderに2つの結果を取得させるにはどのようにすればよいのでしょうか?

よろしくお願いします。
こんにちわ。

> cmd.CommandText = " SELECT A, B FROM TEST ORDER BY C;"
> cmd.CommandText = cmd.CommandText & "SELECT D FROM TEST2 ORDER BY E"

これだと、SQL文として成り立っていないと思いますよ。
それに、取得できる件数に差が出るので、使いまわすのは無理だと思います。

欲しいデータの詳細が良くわからないのでなんともいえませんが、
TESTのA,Bと、TEST2のDをあわせて1レコードとして扱いたいので有れば、
二つのテーブルを結合してデータを取得するようなSQLを考えればよいと思いますが・・・
■No2702に返信(SHさんの記事)
> こんにちわ。
>
>>cmd.CommandText = " SELECT A, B FROM TEST ORDER BY C;"
>>cmd.CommandText = cmd.CommandText & "SELECT D FROM TEST2 ORDER BY E"
>
> これだと、SQL文として成り立っていないと思いますよ。
> それに、取得できる件数に差が出るので、使いまわすのは無理だと思います。
>
> 欲しいデータの詳細が良くわからないのでなんともいえませんが、
> TESTのA,Bと、TEST2のDをあわせて1レコードとして扱いたいので有れば、
> 二つのテーブルを結合してデータを取得するようなSQLを考えればよいと思いますが・・・

SHさんありがとうございます。

やりたいことは、
@SELECT A, B FROM TEST ORDER BY C の結果
ASELECT D FROM TEST2 ORDER BY E の結果

@とAを持つOracleDataReaderを同プロシージャの中で使用したいのですが
OracleDataReaderを2つ持ちたくはないのです。
ヘルプによるとOracleDataReaderには複数の値を持たせることができ
NextResultメソッドで次の結果に移動できると書いていました。
その際に書くSQLが知りたいです。

よろしくお願いします。
■No2702に返信(SHさんの記事)
> こんにちわ。
>
>>cmd.CommandText = " SELECT A, B FROM TEST ORDER BY C;"
>>cmd.CommandText = cmd.CommandText & "SELECT D FROM TEST2 ORDER BY E"
>
> これだと、SQL文として成り立っていないと思いますよ。
> それに、取得できる件数に差が出るので、使いまわすのは無理だと思います。
>
> 欲しいデータの詳細が良くわからないのでなんともいえませんが、
> TESTのA,Bと、TEST2のDをあわせて1レコードとして扱いたいので有れば、
> 二つのテーブルを結合してデータを取得するようなSQLを考えればよいと思いますが・・・

邪道な方法なら空白項目とUNIONで実現できるかもしれません。
手元にOracleが無いので、実際にできるかは判りませんが…。

例)
cmd.CommandText = "SELECT TEST.A, TEST.B, TEST.C, '' AS D, '' AS E, FROM TEST"
cmd.CommandText = cmd.CommandText & " UNION SELECT '', '', '', TEST2.D, TEST2.E FROM TEST2 ORDER BY TEST.C, TEST2.E"

上記の方法だとTEST2の結果が先にきますので、TESTの結果が先に欲しい時はA,B,CとD,Eの位置を変えればいいでしょう。
こういう方法はあまりお勧めできませんけどね。
> OracleDataReaderに2つの結果を持たせて、NextResultで結果を使いまわしたいのですが、
> 以下のようなSQLを実行するとエラーが発生します。

ソースのどういう個所で例外が発生しているのでしょうか?
また、そのときの、例外の詳細な情報はどうなっていますか?

Try
' 問題のコード
Catch ex As Exception
Debug.WriteLine(ex) ' ここにブレークポイントを置く
End Try

のような形のコードにして、例外の各プロパティ値を見て下さい。

> cmd.CommandText = " SELECT A, B FROM TEST ORDER BY C;"
> cmd.CommandText = cmd.CommandText & "SELECT D FROM TEST2 ORDER BY E"

これだけを見ると特に問題なさそうに見えます。
よねKENさんありがとうございます。

> Try
> ' 問題のコード
> Catch ex As Exception
> Debug.WriteLine(ex) ' ここにブレークポイントを置く
> End Try
>
> のような形のコードにして、例外の各プロパティ値を見て下さい。
結果は以下のようになりました。
at System.Data.OracleClient.OracleConnection.CheckError(OciHandle errorHandle, Int32 rc)
at System.Data.OracleClient.OracleCommand.Execute(OciHandle statementHandle, CommandBehavior behavior, Boolean isReader, Boolean needRowid, OciHandle& rowidDescriptor, ArrayList& refCursorParameterOrdinals)
at System.Data.OracleClient.OracleCommand.Execute(OciHandle statementHandle, CommandBehavior behavior, ArrayList& refCursorParameterOrdinals)
at System.Data.OracleClient.OracleCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.OracleClient.OracleCommand.ExecuteReader()

ただ、これを見ても正直よくわかりません。
読む際のポイントなどあるのでしょうか?
よろしくお願いします。
すいません、記入漏れがありました

最初に
System.Data.OracleClient.OracleException: ORA-00933: SQLコマンドが正しく終了されていません。

で、その後に
at System.Data.OracleClient.OracleConnection.CheckError(OciHandle errorHandle, Int32 rc)
at System.Data.OracleClient.OracleCommand.Execute(OciHandle statementHandle, CommandBehavior behavior, Boolean isReader, Boolean needRowid, OciHandle& rowidDescriptor, ArrayList& refCursorParameterOrdinals)
at System.Data.OracleClient.OracleCommand.Execute(OciHandle statementHandle, CommandBehavior behavior, ArrayList& refCursorParameterOrdinals)
at System.Data.OracleClient.OracleCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.OracleClient.OracleCommand.ExecuteReader()

です。
よろしくお願いします。
SELECTの2連発だよね。こんな書き方できるの?(^O^;)
■No2716に返信(IBugFactoryさんの記事)
> SELECTの2連発だよね。こんな書き方できるの?(^O^;)
>
できるらしいのです。
> できるらしいのです。

それは知りませんでした。おいしい情報ゲット!!(^O^)

# SqlClientでもoleDBでもできるのかなぁ。誰かレポート求む!!>他力本願
■No2718に返信(IBugFactoryさんの記事)

> # SqlClientでもoleDBでもできるのかなぁ。誰かレポート求む!!>他力本願

たしか、できるような気がします。
oleDBのヘルプを見たような気がしますが、urlは忘れちゃいました。
すいません。
>># SqlClientでもoleDBでもできるのかなぁ。誰かレポート求む!!>他力本願
>
> たしか、できるような気がします。
> oleDBのヘルプを見たような気がしますが、urlは忘れちゃいました。
> すいません。

それは知りませんでした!
そんな書き方できるもんなんですねぇ。。

ところで、出ているエラーメッセージ

"SQLコマンドが正しく終了されていません。"

を見ると、やはり実行時のSQLがおかしいようですね。。

デバックでSQL文を出して、SQLPlusとかで流してみてはどうでしょうか。
■No2716に返信(IBugFactoryさんの記事)
> SELECTの2連発だよね。こんな書き方できるの?(^O^;)

SQL Server ユーザーグループ > 分科会 > Webテクノロジー
なんかの記事では、そういうことができるみたいです。
http://www.sqlpassj.org/bunkakai/web/report/040212.aspx

[HOW TO] Visual Basic .NET で DataReader を使用して複数の結果を処理する方法」
(これはストアドに対してNextResultで・・・という例だけど・・・)
http://support.microsoft.com/default.aspx?scid=kb;ja;309490

[PRB] 異なるスキーマを含むバッチ クエリにおいて、列挙された DataReader から不完全な情報が返される
http://support.microsoft.com/default.aspx?scid=kb;ja;308625

等の情報があります。

SQL Serverはいけるようですが、Oracleはサポートしているのでしょうか?>hiroさん

例えば、DB2のDB2eDataReaderではNextResultメソッドはサポートしていませんし。
http://www-306.ibm.com/software/data/db2/everyplace/doc/infocenters/jpn/dbeapr1805.htm


といいながら、ついでに調べてみました。
「OracleDataReader.NextResult メソッド」
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemdataoracleclientoracledatareaderclassnextresulttopic.asp

OracleDataReaderのNextResultのヘルプには、

> このメソッドを呼び出すときは、 REF CURSOR を使用する必要があります。

とありました。うーん、意味はよくわかりません。
が、これってストアドのときのキーワードのように思うので、
バッチクエリには対応していない、という意味のような気がします・・・。
よねKEさんありがとうございます。

> といいながら、ついでに調べてみました。
> 「OracleDataReader.NextResult メソッド」
> http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemdataoracleclientoracledatareaderclassnextresulttopic.asp
>
> OracleDataReaderのNextResultのヘルプには、
>
>>このメソッドを呼び出すときは、 REF CURSOR を使用する必要があります。
>
> とありました。うーん、意味はよくわかりません。
> が、これってストアドのときのキーワードのように思うので、
> バッチクエリには対応していない、という意味のような気がします・・・。

そうなんですよね。まさにそこが不明なんです。
僕も
[REF CURSOR を使用する必要があります]
の意味はよくわからないんですが、NextResultのヘルプには
[OracleDataReader を次の結果に進めます。]
とも書いてあるんですよね。
よねKEさんの予想通り、バッチクエリには対応していないのでしょうか?
ためしに、CommandType プロパティを StoredProcedure に設定してから
executeしてもだめでした。
う〜ん。
ORACLEではできないのかな?
> System.Data.OracleClient.OracleException: ORA-00933: SQLコマンドが正しく終了されていません。

 Oracle でこういったことが可能かどうか知りませんので、的外れかも知れませんけど
単純に最後セミコロンで終わってないからとか‥‥?(^_^;)

> cmd.CommandText = " SELECT A, B FROM TEST ORDER BY C;"
> cmd.CommandText = cmd.CommandText & "SELECT D FROM TEST2 ORDER BY E"
                                                                     ↑

DOBON.NET | プログラミング道 | プログラミング掲示板