Oracle
 sql >> Base de données >  >> RDS >> Oracle

La procédure Oracle ne renvoie pas de résultats lors de l'exécution à partir d'une tâche de script sur SSIS

Tout d'abord, n'utilisez pas OleDb , période. Microsoft vous demande d'utiliser un fournisseur spécifique au fournisseur. Utilisez ODP.NET d'Oracle.

Deuxièmement, pour récupérer le jeu d'enregistrements d'Oracle SP, vous devez renvoyer refCursor .

Modifier : À ce stade, nous savons que vos paramètres sont des tables. Pour traiter cela, vous devez ajouter p.CollectionType = OracleCollectionType.PLSQLAssociativeArray à vos paramètres

Votre code est essentiellement celui-ci :

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;

Je vous vois exécuter un bloc anonyme - vous n'avez pas besoin de le faire car cela vous complique les choses. Ce que vous devez faire est d'utiliser vb.net pour exécuter le package directement.

Conclusion : votre code ORACLE actuel ne fait rien pour sortir les résultats vers .NET. Supprimez le bloc anonyme et vous êtes en affaires.

Voici le code pour traiter votre type de procédure (lire en commentaire)

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

Et c'est la partie la plus importante

La partie la plus importante est la façon dont vous remplissez votre type déclaré. Prenons

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;

Ceci (ci-dessus) fonctionnera. Mais cela échouera :

v_num(0) := 1234567890;
v_num(1) := 2345678901;
v_num(2) := 3456789012;

Et enfin, cela fonctionnera à une condition

v_num(2) := 1234567890;
v_num(3) := 2345678901;
v_num(4) := 3456789012;

Ici, nous aurons 4 membres dans p1.Value mais sous l'index 0 vous aurez oracle null . Donc, vous devrez vous en occuper ici (si vous avez une telle condition)

' instead of this 
myP2Values(i) = Convert.ToInt64(oraNumbers(i).Value)
' you will need first to check 
If oraNumbers(i).IsNull Then 
. . . . 

Donc, la chose principale ici est, QUEL est l'index de votre table pl/sql ? ! Il doit commencer à partir de quelque chose de plus grand que 0 , et de préférence de 1 . Et si vous avez un index avec des numéros sautés, c'est-à-dire 2,4,6,8 , tous ces espaces feront partie du tableau oracle renvoyé et il y aura oracle null en eux

Voici quelques références