Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Prosedur Oracle tidak mengembalikan hasil saat menjalankan dari tugas skrip di SSIS

Pertama-tama, jangan gunakan OleDb , Titik. Microsoft memberitahu Anda untuk menggunakan penyedia khusus vendor. Gunakan ODP.NET Oracle.

Kedua, untuk mengambil recordset dari Oracle SP, Anda harus mengembalikan refCursor .

Sunting: Saat ini kami tahu bahwa parameter Anda adalah tabel. Untuk memproses ini, Anda perlu menambahkan p.CollectionType = OracleCollectionType.PLSQLAssociativeArray ke parameter Anda

Kode Anda pada dasarnya adalah ini:

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;

Saya melihat Anda mengeksekusi blok anonim - Anda tidak perlu melakukan ini karena ini memperumit Anda. Yang perlu Anda lakukan adalah menggunakan vb.net untuk mengeksekusi paket secara langsung.

Intinya: kode ORACLE Anda saat ini tidak melakukan apa pun untuk menampilkan hasil ke .NET. Hapus blokir anonim dan Anda berada dalam bisnis.

Berikut adalah kode untuk memproses jenis prosedur Anda (baca di komentar)

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

Dan ini adalah bagian Terpenting

Bagian terpenting adalah bagaimana Anda mengisi tipe yang Anda nyatakan. Ayo ambil

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;

Ini (di atas) akan berhasil. Tapi ini akan gagal:

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

Dan akhirnya, ini akan berhasil dengan satu syarat

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

Di sini kita akan mendapatkan 4 anggota di p1.Value tetapi di bawah indeks 0 anda akan memiliki oracle null . Jadi, Anda perlu mengatasinya di sini (jika Anda memiliki kondisi seperti itu)

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

Jadi, hal utama di sini adalah, APA indeks tabel pl/sql Anda?! Itu harus dimulai dari sesuatu yang lebih besar dari 0 , dan sebaiknya dari 1 . Dan jika Anda memiliki indeks dengan angka yang dilewati, yaitu 2,4,6,8 , semua spasi itu akan menjadi bagian dari array oracle yang kembali dan akan ada oracle null di dalamnya

Ini beberapa referensi




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. BITAND() Fungsi di Oracle

  2. Apakah zona waktu java.sql.Timestamp spesifik?

  3. Bagaimana mengantisipasi dan menghindari kutipan tunggal ' di oracle

  4. Bagaimana cara memasukkan cap waktu di Oracle?

  5. Cara memasukkan data langsung dari Excel ke Oracle Database