简体   繁体   中英

How do you Send More that 20 Parameters to a Stored Procedure Using ODP.Net?

Switching from Microsofts Oracle Driver to ODP.NET version 10.2.0.100. After changing the data types to OracleDBTypes in a procedure, that worked perficetly using System.Data.OracleClient, the procedure fails if we try and pass in more that 20 parameters. The error returned is:

ORA-06550: line 1, column 7: PLS-00306: wrong number or types of arguments in call to 'ADD_TARP_EVENT' ORA-06550: line 1, column 7: PL/SQL: Statement ignorede

If we reduce the number of parameters to less than 20 it works. Is this a known issue?

Here the code for creating the parameters:

    Shared Function CreateTarpEventCommand(ByVal aTarpEvent As TARPEventType) As OracleCommand
    Dim cmd As New OracleCommand

    With aTarpEvent

        cmd.Parameters.Add(New OracleParameter("I_facID_C", OracleDbType.Char)).Value = .FacilityShortName
        cmd.Parameters.Add(New OracleParameter("I_facName_VC", OracleDbType.Varchar2)).Value = .FacilityLongName
        cmd.Parameters.Add(New OracleParameter("I_client_VC", OracleDbType.Varchar2)).Value = .ComputerNameTarpIsRunningOn
        cmd.Parameters.Add(New OracleParameter("I_TARP_Version_VC", OracleDbType.Varchar2)).Value = .TarpVersionNumber
        cmd.Parameters.Add(New OracleParameter("I_NAS_Type_VC", OracleDbType.Varchar2)).Value = .FacilityNASSystemType
        cmd.Parameters.Add(New OracleParameter("I_Aircraft1_Callsign_VC", OracleDbType.Varchar2)).Value = .Aircraft1Callsign

        If .Aircraft1Type Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_Aircraft1_Type_VC", OracleDbType.Varchar2)).Value = .Aircraft1Type
        End If

        If .Aircraft1Category Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_Aircraft1_Cat_VC", OracleDbType.Varchar2)).Value = .Aircraft1Category
        End If

        cmd.Parameters.Add(New OracleParameter("I_Aircraft2_Callsign_VC", OracleDbType.Varchar2)).Value = .Aircraft2Callsign

        If .Aircraft2Type Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_Aircraft2_Type_VC", OracleDbType.Varchar2)).Value = .Aircraft2Type
        End If

        If .Aircraft2Category Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_Aircraft2_Cat_VC", OracleDbType.Varchar2)).Value = .Aircraft2Category
        End If

        If .SensorShortName Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_Sensor_Name_VC", OracleDbType.Varchar2)).Value = .SensorShortName
        End If


        If .TarpConfigurationName Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_TARP_Config_Name_VC", OracleDbType.Varchar2)).Value = .TarpConfigurationName
        End If

        If .EntryCreatorID Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_Create_VC", OracleDbType.Varchar2)).Value = .EntryCreatorID
        End If

        If .LogAction Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_Log_Action_VC", OracleDbType.Varchar2)).Value = .LogAction
        End If

        cmd.Parameters.Add(New OracleParameter("I_TARP_Mode_VC", OracleDbType.Varchar2)).Value = .TarpOperatingMode
        cmd.Parameters.Add(New OracleParameter("I_Min_Loss_N", OracleDbType.Decimal)).Value = .ClosestMeasureOfLoSS

        If .MapName Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_MAP_NAME_VC", OracleDbType.Varchar2)).Value = .MapName
        End If

        If .TarpConfigurationFileHash Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_CONFIG_HASH_VC", OracleDbType.Varchar2)).Value = .TarpConfigurationFileHash
        End If

        Dim aDate As OracleDate = CType(.LossEventsMessages(0).LossEventTime, System.DateTime)
        cmd.Parameters.Add(New OracleParameter("I_FIRST_LOSS_EVENT_DATE", OracleDbType.Date)).Value = aDate
        cmd.Parameters.Add(New OracleParameter("I_FIRST_LOSS_EVENT_MS_N", OracleDbType.Int32)).Value = .LossEventsMessages(0).LossEventMilliSeconds

        If .ZippedMapFiles Is Nothing Then
            cmd.Parameters.Add(New OracleParameter("I_Map_File_BL", OracleDbType.Blob)).Value = .ZippedMapFiles
        End If

        cmd.Parameters.Add(New OracleParameter("I_TARP_Package_BL", OracleDbType.Blob)).Value = .ZippedTarpPackageWithoutMaps

        cmd.Parameters.Add(New OracleParameter("rs_RESULTS", OracleDbType.RefCursor)).Direction = ParameterDirection.Output

    End With
    Return cmd
End Function

And here is the code for executing the procedure:

 Dim workingDataSet As New DataSet
    Dim oracleConnection As New OracleConnection
    Dim cmd As New OracleCommand
    Dim oracleDataAdapter As New OracleDataAdapter

    Try

         Using oracleConnection
            oracleConnection.ConnectionString = System.Configuration.ConfigurationManager.AppSettings("MasterConnectionODT")
            cmd = HelperDB.CreateTarpEventCommand(TarpEvent)

            cmd.Connection = oracleConnection
            cmd.CommandText = "LOADER.ADD_TARP_EVENT"
            cmd.CommandType = CommandType.StoredProcedure

            Using oracleConnection
                oracleConnection.Open()
                Dim aTransation As OracleTransaction = oracleConnection.BeginTransaction(IsolationLevel.ReadCommitted)
                Try
                    Using oracleDataAdapter
                        oracleDataAdapter = New OracleDataAdapter(cmd)
                        oracleDataAdapter.TableMappings.Add("Results", "rs_Max")
                        oracleDataAdapter.Fill(workingDataSet)

....

It would surprise me since 20 isn't such a high number, I'd think it's more likely that you're getting some parameter mixed up (easy enough to do when it's over 20 of them).

But to try it out I suggest creating a procedure with 21 parameters, all being Numbers and then sending in 1 to all of them, that way you could make sure that it's not just a mistype.

There are two ways of calling oracle procedures. The first is named notation

proc (p_1 => 'test', p2 => 1);

The second is positional

proc ('test', 1);

In named notation, you can put the parameters in any order and omit any that are defined with a DEFAULT. In positional notation, they must be in the order they are defined in and only the last ones can be omitted. That is, if you supply five parameters and the procedure has six defined, then it assumes the missing one is the sixth. Again, the sixth must have a DEFAULT. An output parameter cannot have a default and must be supplied.

I'm not sure how ODP works to choose which to use (though it could be confirmed by tracing the session using DBMS_MONITOR and looking at the resultant trace file).

Anyway, check that the names of the parameters match those in your code. Oracle treats identifiers as uppercase unless quoted. Also, if any parameters do not have a DEFAULT, they MUST be set in the call (even if set to null).

The stored procedure "LOADER.ADD_TARP_EVENT" defaulted the procedure parameter values to Null where applicable on the server side. When we built the ADO Oracle Command we did not populate the Null parameters, as they were already set to default to Null in the procedure. This worked great with ADO.NET. ODT aparently requires that the values be passed in as dbNull. Once we passed in dbNull for the values all worked as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM