- PR -

バインド変数で「Number」フィールドを更新

1
投稿者投稿内容
Strider
会議室デビュー日: 2006/08/16
投稿数: 6
投稿日時: 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の例外は発生します。

この件で原因・解決策をご存知の方がみえましたらご教授願います。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-09-06 19:56
引用:

Striderさんの書き込み (2006-09-06 19:24) より:

コード:
            objCommand.ArrayBindCount = 2


「strParm1」、「decParm2」の値を上記のように2要素以上指定すると例外は
発生しないのですが、値を1要素のみに変更すると例外が発生するのを確認しました。


確認です。
バインド配列で更新しようとしていますが、
これは思ったとおりのコーディングですか?
Strider
会議室デビュー日: 2006/08/16
投稿数: 6
投稿日時: 2006-09-06 20:05
かるあさん

すみません。お返事いただいた中の質問の意味を100%こちらで
解釈できませんが、もちろん、値を1要素のみで更新する場合;

objCommand.ArrayBindCount = 1

Dim strParm1 As String() = {"TEST1"}
---
Dim decParm2 As Decimal() = {100}
---

で記述して実行しております。
この時にCastの例外が発生するということです。
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 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 ]
Strider
会議室デビュー日: 2006/08/16
投稿数: 6
投稿日時: 2006-09-06 21:18
masa さん ご返事有難うございます。

ODP.Net 9.2 の OracleParameter では「CollectionType」は
ありません。

ちなみに漠然と思っただけでまだ試していませんが、「Value」プロパティの
設定後に「ArrayBindStatus」プロパティの設定も必要なのでしょうか?
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-09-06 21:36
引用:

Striderさんの書き込み (2006-09-06 20:05) より:

すみません。お返事いただいた中の質問の意味を100%こちらで
解釈できませんが、もちろん、値を1要素のみで更新する場合;


すいません、惑わせてしまったようですね。
decParm1 と decParm2 の要素数は変動するんですよね。

よさそうな感じではあるんですけれどね
@ITのこのページが参考になります。
http://www.atmarkit.co.jp/fdb/rensai/odpdotnet01/odpdotnet04.html


要素が一つに固定されるなら、
↓これでいいじゃんと思ったのです。
コード:
Dim strParm1 As String = "TEST1"
Dim decParm2 As Decimal = 100


かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-09-06 21:37
引用:

Striderさんの書き込み (2006-09-06 21:18) より:

ODP.Net 9.2 の OracleParameter では「CollectionType」は
ありません。


確か PL/SQL配列 は ODP.NET 9.2.0.4 からのサポートだったと思います。
_________________
かるあ のメモスニペット
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 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

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