まず、OleDb
を使用しないでください 、 限目。 Microsoftは、ベンダー固有のプロバイダーを使用するように指示しています。 OracleのODP.NETを使用します。
次に、Oracle SPからレコードセットを取得するには、refCursor
を返す必要があります。 。
編集: 現時点では、パラメータがテーブルであることがわかっています。これを処理するには、p.CollectionType = OracleCollectionType.PLSQLAssociativeArray
を追加する必要があります パラメータに
あなたのコードは本質的にこれです:
Declare
obus_grp_id PKG_HOBS.Tnumber; -- numeric table value
ostat_c PKG_HOBS.Tnumber; -- numeric table value
ostat_msg_x PKG_HOBS.Tmsg_500; -- string table value
BEGIN
PKG_HOBS.PRC_HOBS_GET_CLIENTID(obus_grp_id, ostat_c, ostat_msg_x);
END;
私はあなたが匿名ブロックを実行しているのを見ます-これはあなたにとって物事を複雑にするのであなたはこれをする必要はありません。必要なのは、vb.netを使用してパッケージを直接実行することです。
結論: 現在のORACLEコードは、結果を.NETに出力するために何もしません。匿名のブロックを削除すると、ビジネスを開始できます。
これがあなたのタイプの手順を処理するためのコードです(コメントを読んでください)
Dim cmd As New OracleCommand("PKG_HOBS.PRC_HOBS_GET_CLIENTID", conn)
cmd.CommandType = CommandType.StoredProcedure
Dim p1 As New OracleParameter(":p1", OracleDbType.Int64, ParameterDirection.Output)
p1.CollectionType = OracleCollectionType.PLSQLAssociativeArray
p1.Size = 100 ' Declare more than you expect
' This line below is not needed for numeric types (date too???)
' p1.ArrayBindSize = New Integer(99) {}
cmd.Parameters.Add(p1)
' Add parameter 2 here - same as 1
Dim p3 As New OracleParameter(":p3", OracleDbType.Varchar2, ParameterDirection.Output)
p3.CollectionType = OracleCollectionType.PLSQLAssociativeArray
p3.Size = 100 ' Declare more than you expect
' for string data types you need to allocate space for each element
p3.ArrayBindSize = Enumerable.Repeat(500, 100).ToArray() ' get 100 elements of 500 - size of returning string
' I don't know why you have problems referencing System.Linq but if you do...
'Dim intA() As Integer = New Integer(99) {}
'For i as integer = 0 to intA.Length -1
' intA(i) = 500
'Next
cmd.Parameters.Add(p3)
conn.Open()
cmd.ExecuteNonQuery()
' Ora number is not compatible to .net types. for example integer is something
' between number(9) and (10). So, if number(10) is the type - you get Long in
' return. Therefore use "Convert"
' Also, you return arrays, so you need to process them as arrays - NOTE CHANGES
Dim oraNumbers() As OracleDecimal = CType(p1.Value, OracleDecimal())
Dim myP1Values(oraNumbers.Length - 1) As Long
For i as Integer = 0 To oraNumbers.Length - 1
myP1Values(i) = Convert.ToInt64(oraNumbers(i).Value)
Next
oraNumbers = CType(p2.Value, OracleDecimal())
Dim myP2Values(oraNumbers.Length - 1) As Long
For i as Integer = 0 To oraNumbers.Length - 1
myP2Values(i) = Convert.ToInt64(oraNumbers(i).Value)
Next
Dim oraStrings() As OracleString= CType(p3.Value, OracleString())
Dim myP3Values(oraStrings.Length - 1) As String
For i as Integer = 0 To oraStrings.Length - 1
myP3Values(i) = oraStrings(i).Value
Next
そしてこれは最も重要な部分です
最も重要な部分は、宣言されたタイプをどのように入力するかです。取りましょう
TYPE Tnumber IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_num Tnumber;
v_num(1) := 1234567890;
v_num(2) := 2345678901;
v_num(3) := 3456789012;
これ(上記)は機能します。しかし、これは失敗します:
v_num(0) := 1234567890;
v_num(1) := 2345678901;
v_num(2) := 3456789012;
そして最後に、これは1つの条件で機能します
v_num(2) := 1234567890;
v_num(3) := 2345678901;
v_num(4) := 3456789012;
ここでは、p1.Value
に4つのメンバーを取得します ただし、インデックス0
の下にあります oracle null
があります 。したがって、ここで対処する必要があります(そのような状態の場合)
' instead of this
myP2Values(i) = Convert.ToInt64(oraNumbers(i).Value)
' you will need first to check
If oraNumbers(i).IsNull Then
. . . .
つまり、ここで重要なのは、pl/sqlテーブルのインデックスは何ですか。 0
より大きいものから開始する必要があります 、できれば1
から 。 また、番号がスキップされたインデックスがある場合、つまり2,4,6,8
、これらのスペースはすべて、返されるoracle配列の一部になり、oracle null
が存在します。 それらの中で
ここにいくつかの参考資料があります