- PR -

ODP.NETのパラメータクエリーについて

投稿者投稿内容
とら
ベテラン
会議室デビュー日: 2006/10/04
投稿数: 54
投稿日時: 2006-10-04 10:19
VisualStudio2005のC#でODP.NET(9.2.0.2102)を使用した環境で
パラメータクエリーを書いているんですが、パラメータがSelect句の
中にあるときに限って、
ORA-01036: 変数の名前/数が無効です。
が出てしまいます。

具体的には以下のようなコード(抜粋)です。

OracleCommand myOraCommand = new OracleCommand();
myOraCommand.Connection = mDbConn;
myOraCommand.CommandText = "select :001,FLD01 as FLD01 from TBL01 WHERE FLD03 = :002";
myOraCommand.Parameters.Add(new OracleParameter("001", "ZZZZ"));
myOraCommand.Parameters.Add(new OracleParameter("002", "S001"));
OracleDataReader myOraReader = myOraCommand.ExecuteReader(CommandBehavior.CloseConnection);

上記のようにSelect句の中にパラメータが存在する場合に、前述のエラーが
出るようです。
Select句の中のパラメータを除去してWhere句の方だけにした場合は
正しく実行されています。

また、同様の方法でSQLServerに対してSystem.Data.SqlClientを使用して
アクセスした場合はSelect句の中にパラメータが存在しても問題なく動くようです。

もしかしたら、ODP.NETの仕様もしくは障害でしょうか、それとも私の認識が
違っているのでしょうか?

何が、ご存知の情報がありましたら、教えてください。

よろしくお願いします。
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2006-10-04 10:31
select :001,FLD01 as FLD01 from TBL01 WHERE FLD03 = :002";
 ↓
select :001 as PRM001, FLD01 as FLD01 from TBL01 WHERE FLD03 = :002";

:001 にはリテラルな値が入りますから、
エイリアスで列名を指定する必要があるのではないでしょうか。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-10-04 11:23
本当ですね、僕のほうでも同じエラー ora-01036 が発生しました。
別名をつけても同様のエラーが出ました。

無理やりですが、こんな方法で回避してみました。
どうも直接バインド変数の値を返せない見たいなので、インラインにしてみました。
コード:
myOraCommand.CommandText = "select c001, fld01 from (select :001 As c001, FLD01 as FLD01 from TBL01 WHERE FLD03 = :002"); 


_________________
かるあ のメモスニペット
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2006-10-04 11:58
私も試してみました。バージョンは 10.1.0.4 です。

同じDBエラーになりました。
Direction を変更してみたりしましたが変わらないようです。

かるあさんがおっしゃるとおりインライン化すれば返せるようで、
これでもいけるみたいです。

select
( select :001 from dual ) as PRM001,
FLD01 as FLD01
from TBL01 WHERE FLD03 = :002";


<追記>

オブジェクトブラウザで実行すると問題なく結果は取得できるようで、
SQL文自体にも問題はないはず。
となると ODP.NET の仕様なんでしょうか。
オブジェクトブラウザは odbc でしたっけ?


[ メッセージ編集済み 編集者: masa 編集日時 2006-10-04 12:18 ]

[ メッセージ編集済み 編集者: masa 編集日時 2006-10-04 12:19 ]
とら
ベテラン
会議室デビュー日: 2006/10/04
投稿数: 54
投稿日時: 2006-10-05 09:27
回答有難うございました。

どうやら、ほかの皆さんの所でも発生しているようですね。
仕様なんでしょうか・・・・

でも、なんとなくバグくさいですね(笑)
とら
ベテラン
会議室デビュー日: 2006/10/04
投稿数: 54
投稿日時: 2006-10-05 10:16
ちょっと追加の報告です。

だめもとで、以下のようなSQLを書いたところ、ちゃんと動きました。
myOraCommand.CommandText = "select (select 'a' from dual where dummy = :01) as aaa,:02 as bbb from TestTable";

ここで不思議なのは、最初のサブクエリー内の:01が通ることもですが、
:02もちゃんと動くことです。

これを書き換えて、
myOraCommand.CommandText = "select :02 as bbb from TestTable";
こうすると、やはりだめでした。

また、
myOraCommand.CommandText = "select (select 'a' from dual where dummy = 'X') as aaa,:02 as bbb from TestTable";
これもだめでした。

どうやら、
パラメータがSelect句に直接埋め込まれていて、かつそのパラメータが最初に現れるパラメータである場合に正しく動かないという条件のようです。

まあ、回避策もあるので、良しとするしかないようですね。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-10-05 11:06
引用:

masaさんの書き込み (2006-10-04 11:58) より:

オブジェクトブラウザで実行すると問題なく結果は取得できるようで、
SQL文自体にも問題はないはず。
となると ODP.NET の仕様なんでしょうか。
オブジェクトブラウザは odbc でしたっけ?


仕様なのか不具合なのか、何か見落としがあるのか。。。
KROWN にもそれらしい記述は無いようですね。

オブジェクトブラウザは ODBC 定義しなくても使えるので、
OCI を直にたたいてるか、もしくは OO4O あたりを使ってるんじゃないかな。
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2006-10-05 12:45
引用:

とらさんの書き込み (2006-10-05 10:16) より:
どうやら、
パラメータがSelect句に直接埋め込まれていて、かつそのパラメータが最初に現れるパラメータである場合に正しく動かないという条件のようです。

まあ、回避策もあるので、良しとするしかないようですね。



確かにパラメーターの出現順は重要な意味をもってはいますが、
「先頭だけだめ」というのは、知っていないとはまりそうですね。

パラメーター名でバインドするか出現順でバインドするかどうかはプロパティにあり、
デフォルトは出現順であったと思います。

※いま確かめられる環境がないもので、記憶のみです。

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