- - PR -
バインド変数で「Number」フィールドを更新
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-09-06 19:24
Strider です。
現在 VB2005 & ODP.Net 9.2 でWindowsアプリケーションを開発中です。 OracleDBのテーブル(TBL01)をパラメータのバインド変数の値で更新したいのですが、 ExecuteNonQueryメッソドで以下のような例外が発生します。 「System.InvalidCastException: 型 'System.Decimal[]' のオブジェクトを 型 'System.IConvertible' にキャストできません。」 TBL01のデザインは、 フィールド「STR1」が データ型「Varchar2」 サイズ「128」 フィールド「NUM1」が データ型「Number」 サイズ「22」 です。 Const PARAM1)As String = ":STR1" Const PARAM2 As String = ":NUM1" Dim stbINS As New StringBuilder stbINS.Append("INSERT INTO TBL01 ") stbINS.Append(" (STR1,") stbINS.Append(" NUM1)") stbINS.Append(" VALUES ") stbINS.Append(" (" & PARAM1) stbINS.Append(" ," & PARAM2 & ”)”)] Dim objCommand As New OracleCommand objCommand.Connection = ’***** 此処では省略 objCommand.CommandText = stbINS.ToString objCommand.CommandType = CommandType.Text objCommand.BindByName = True objCommand.ArrayBindCount = 2 Dim strParm1 As String() = {"TEST1", "TEST2"} objCommand.Parameters.Add(PARAM1, _ OracleDbType.Varchar2, _ 128, _ ParameterDirection.Input).Value = strParm1 Dim decParm2 As Decimal() = {100, 0} objCommand.Parameters.Add(PARAM2, _ OracleDbType.Decimal, _ 22, _ ParameterDirection.Input).Value = decParm2 objCommand.ExecuteNonQuery() 「strParm1」、「decParm2」の値を上記のように2要素以上指定すると例外は 発生しないのですが、値を1要素のみに変更すると例外が発生するのを確認しました。 また「STR1」のみ更新すると問題なくTBL01は更新されますが、「NUM1」もSQL文に 含めて更新しようとすると例外が発生するのも確認済みです。 「NUM1」パラメータの「OracleDbType」を「Int32」等の他の数値データ型に変えても 同じCastの例外は発生します。 この件で原因・解決策をご存知の方がみえましたらご教授願います。 | ||||||||
|
投稿日時: 2006-09-06 19:56
確認です。 バインド配列で更新しようとしていますが、 これは思ったとおりのコーディングですか? | ||||||||
|
投稿日時: 2006-09-06 20:05
かるあさん
すみません。お返事いただいた中の質問の意味を100%こちらで 解釈できませんが、もちろん、値を1要素のみで更新する場合; objCommand.ArrayBindCount = 1 Dim strParm1 As String() = {"TEST1"} --- Dim decParm2 As Decimal() = {100} --- で記述して実行しております。 この時にCastの例外が発生するということです。 | ||||||||
|
投稿日時: 2006-09-06 20:58
私の担当する物件は .NET1.1 & ODP.NET10.1.0.4 ですが、
このようにして配列を渡し、PL/SQL ファンクションを実行しています。 ファンクションの中では受け取った配列を使ってバルク更新を行っています。 ※全くそのままのコードではありません。 ' imports Oracle.DataAccess.Client ' imports System.Data 'セットする値を格納した配列 dim value() as object 'パラメーター(中身は ODP.NET のパラメーターオブジェクト) dim prm as IDbDataParameter '値が配列であることと、そのサイズを指定 prm.CollectionType = OracleCollectionType.PLSQLAssociativeArray prm.Size = value.Length '値を設定 prm.Value = value ただ、"PLSQLAssociativeArray" とあるので、 PL/SQL専用の方法かもしれません。 [ メッセージ編集済み 編集者: masa 編集日時 2006-09-06 20:59 ] [ メッセージ編集済み 編集者: masa 編集日時 2006-09-06 21:01 ] | ||||||||
|
投稿日時: 2006-09-06 21:18
masa さん ご返事有難うございます。
ODP.Net 9.2 の OracleParameter では「CollectionType」は ありません。 ちなみに漠然と思っただけでまだ試していませんが、「Value」プロパティの 設定後に「ArrayBindStatus」プロパティの設定も必要なのでしょうか? | ||||||||
|
投稿日時: 2006-09-06 21:36
すいません、惑わせてしまったようですね。 decParm1 と decParm2 の要素数は変動するんですよね。 よさそうな感じではあるんですけれどね @ITのこのページが参考になります。 http://www.atmarkit.co.jp/fdb/rensai/odpdotnet01/odpdotnet04.html 要素が一つに固定されるなら、 ↓これでいいじゃんと思ったのです。
| ||||||||
|
投稿日時: 2006-09-06 21:37
確か PL/SQL配列 は ODP.NET 9.2.0.4 からのサポートだったと思います。 _________________ かるあ のメモ と スニペット | ||||||||
|
投稿日時: 2006-09-06 22:25
9.2.4 からでしたか。
Oracle のマイナーバージョンの違いは無視できませんね、ほんとに。 > 「System.InvalidCastException: 型 'System.Decimal[]' のオブジェクトを > 型 'System.IConvertible' にキャストできません。」 とありますから、配列としてみていないと思われますが、 > objCommand.Parameters.Add(PARAM1, _ > OracleDbType.Varchar2, _ > 128, _ > ParameterDirection.Input).Value = strParm1 パラメーターオブジェクトをつくるときに、 Size を指定しないようにしてみてはどうでしょうか。 指定しなくてもほとんどの場合は処理されますし。 Size プロパティがデータの長さなのか、配列の要素数なのか、 その他のプロパティとの兼ね合いによって判断されているように見えます。 |
1