From within .NET (ODP.NET) how can I access an oracle parameter by name?

60 views Asked by At

Using ODP & VB.NET, I create insert statements with parameters, similar to the following code:

Dim objOracleParameter As OracleParameter
Dim objCommand As New OracleCommand

objOracleParameter = New OracleParameter
objOracleParameter.ParameterName = ":TestField"


objOracleParameter.OracleDbType = [Enum].Parse(GetType(OracleDbType), "Varchar2")
objOracleParameter.Value = "Data1"
Dim strSQL As String = "INSERT INTO MyTable (TestField) Values (:TestField)"
objCommand.Parameters.Add(objOracleParameter)
objCommand.CommandText = strSQL
objCommand.ExecuteNonQuery()

objOracleParameter = New OracleParameter
objOracleParameter.ParameterName = ":TestField"

objCommand = New OracleCommand

objOracleParameter.OracleDbType = [Enum].Parse(GetType(OracleDbType), "Varchar2")
objOracleParameter.Value = "Data2"
Dim strSQL As String = "INSERT INTO MyTable (TestField) Values (:TestField)"
objCommand.Parameters.Add(objOracleParameter)
objCommand.CommandText = strSQL
objCommand.ExecuteNonQuery()

Currently, I execute this code for each record I want to insert, which I believe is inefficient. Instead, I would like to create the command once and then change the parameter value for each new value I want to insert. However, I have been unable to find an example of how to do this and I am not sure if it can't be done. My pseudo code describing what I would like to do is below. Please note that I would like to update only the parameter values and leave everything else unchanged:

Dim objOracleParameter As OracleParameter
Dim objCommand As New OracleCommand

objOracleParameter = New OracleParameter
objOracleParameter.ParameterName = ":TestField"

objOracleParameter.OracleDbType = [Enum].Parse(GetType(OracleDbType), "Varchar2")
objOracleParameter.Value = "Data1"
Dim strSQL As String = "INSERT INTO MyTable (TestField) Values (:TestField)"
objCommand.Parameters.Add(objOracleParameter)
objCommand.CommandText = strSQL
objCommand.ExecuteNonQuery()

objOracleParameter(":TestField").Value = "Data2"
objCommand.ExecuteNonQuery()

Update:

I simplified what I am doing above. The actual use case is in the creation of a generalized routine which allows validating and importing data into various tables by defining the data layout in a table and using it to parse & validate the data. The routine currently works, but I am trying to improve performance.

The largest file I have found which I need to import has > 700,000 lines with ~45 fields each. Implementing performance improvements is critical.

1

There are 1 answers

1
Joel Coehoorn On

The largest file I have found which I need to import has > 700,000 lines with ~45 fields each.

That sounds like a job for the OracleBulkCopy type. Performance will be MUCH better.

But sometimes you do have a reasonable set of records to process in a tight loop. For that purpose I would structure the code like below.

Dim SQL As String = "
INSERT INTO MyTable (StringField1, IntField2, DateTimeField3) 
VALUES 
( :StringField1, :IntField2, :DateTimeField3);"

' Returns a collection of objects with properties matching the query above
Dim data = GetDataForInsert() 

Using cn As New OracleConnection("connection string here"), _
      cmd As New OracleCommand(SQL, cn)

    Dim sf1 = cmd.Parameters.Add(":StringField1", OracleDbType.NVarchar2, 30)
    Dim if2 = cmd.Parameters.Add(":IntField2", OracleDbType.Int32)
    Dim df3 = cmd.Parameters.Add(":DateTimeField3", OracleDbType.Date)

    cn.Open()
    For Each item In Data
        sf1.Value = item.StringField1
        if2.Value = item.IntField2
        df3.Value = item.DateTimeField3

        ' OR
        cmd.Parameters(":StringField1").Value = item.StringField1
        cmd.Parameters(":IntField2").Value = item.IntField2
        cmd.Parameters(":DateTimeField3").Value = item.DateTimeField3
 
        ' One or the other of the above blocks, not both

        cmd.ExecuteNonQuery()
    Next
End Using