sql >> データベース >  >> RDS >> Oracle

SSISのスクリプトタスクから実行すると、Oracleプロシージャが結果を返さない

    まず、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が存在します。 それらの中で

    ここにいくつかの参考資料があります




    1. OracleDatabase18cでのCDBフリートの管理

    2. Microsoft SQL Serverエラー926を修正する方法?-解決しました

    3. .NETのMath.Maxのように2つの値を取るSQLServerのMax関数はありますか?

    4. SQLiteDiskIOException:エラーコード10:ICSでのディスクI / Oエラーの再調整、およびDROPTABLEでのSamsungNexus