Oracle
 sql >> база данни >  >> RDS >> Oracle

Процедурата на Oracle не връща резултати при изпълнение от задача на скрипт на SSIS

На първо място, не използвайте OleDb , месечен цикъл. Microsoft ви казва да използвате специфичен доставчик на доставчик. Използвайте ODP.NET на Oracle.

Второ, за да извлечете набор от записи от 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;

И накрая, това ще работи с едно условие

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

Тук ще получим 4 члена в p1.Value но под индекс 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Грешка при изключване на PDB ORA-17528

  2. ЗАДАЙТЕ SQLBLANKLINES:Как да разрешите празни редове в SQLcl &SQL*Plus

  3. Препращане към типовете, дефинирани от потребителя на Oracle, през DBLINK?

  4. Oracle - Как да създадете материализиран изглед с БЪРЗО ОБНОВЯВАНЕ и ПРИСЪЕДИНЕНИЯ

  5. Показване на имена на всички ограничения за таблица в Oracle SQL