Filling Datasets from Oracle within VB Threads
I'm trying to run a couple of PL/SQL procedures from within a VB app. The procedures take a while to run so I intend to put them into separate threads (the subject of which I am new to)
Currently, each thread calls a function, which in turn calls the following code:
' Function getDataSet
' builds a data set from given information
' Parameters:
' aCommand - the PL/SQL procedure to call
' aParamCollection - an oraParameterCollection object containing all the parameters
' aDataSet - a data set to hold the results
' Returns:
' number of rows retrieved
Public Function getDataSet( _
ByVal aCommand As String, _
ByVal aParamCollection As oraParameterCollection, _
ByRef aDataSet As DataSet _
) As Integer
Dim result As Integer = 0
' define commands etc
Dim cmd As OracleCommand = New OracleCommand(aCommand, dbConn)
cmd.CommandType = CommandType.StoredProcedure
' add parameters for the query
For i As Integer = 0 To aParamCollection.getParameterCount() - 1
cmd.Parameters.Add(New OracleParameter( _
aParamCollection.getParameterByIndex(i).ParameterName, _
aParamCollection.getParameterByIndex(i).ParameterType)).Value = _
aParamCollection.getParameterByIndex(i).ParameterValue
Next
Dim param As OracleParameter = New OracleParameter("io_cursor", OracleDbType.RefCursor)
cmd.Parameters.Add(param).Direction = ParameterDirection.Output
CheckConnection()
cmd.ExecuteNonQuery()
Dim cur As OracleRefCursor
cur = param.Value
cmd.Dispose()
Dim theAdaptr As New OracleDataAdapter
If aDataSet IsNot Nothing Then
theAdaptr.Fill(aDataSet, cur)
result = aDataSet.T开发者_开发问答ables(0).Rows.Count
End If
Return result
End Function
Where:
aCommand = the PL/SQL proc to execute aParamCollection = a custom class that holds parameters, types and values aDataSet = the data set to hold the resulting dataHowever, when I run the app, I get an access violation at this point:
theAdaptr.Fill(aDataSet, cur)
I assume that the separate threads can't make the call to Fill at the same time, is this correct? I am currently kicking off each thread as so:
Dim th_Mean As New Thread(AddressOf getMeanData)
Dim th_Stdev As New Thread(AddressOf getStdevData)
th_Mean.Name = "th_Mean"
th_Stdev.Name = "th_Stdev"
th_Mean.Start()
th_Stdev.Start()
Do While th_Mean.IsAlive Or th_Stdev.IsAlive
Loop
Ultimately, my question is, what should I be doing so as to avoid the access violation happening?
Thanks for reading BBz
Have you considered adding the parallelism in the database? Parallelism is (relatively) easy with declarative SQL. Depending on your stored procedures, it may be as simple as finding the slow query and adding a hint, something like:
select /*+ parallel(my_table) */ * from my_table;
If the procedure is more about row-by-row processing than queries you may need to look into parallel pipelined functions.
精彩评论