0

从 Microsoft 的 Oracle 驱动程序切换到 ODP.NET 版本 10.2.0.100。在过程中将数据类型更改为 OracleDBTypes 后,该过程使用 System.Data.OracleClient 完美运行,如果我们尝试传入超过 20 个参数,则该过程将失败。返回的错误是:

ORA-06550:第 1 行,第 7 列:PLS-00306:调用“ADD_TARP_EVENT”时参数的数量或类型错误 ORA-06550:第 1 行,第 7 列:PL/SQL:语句被忽略e

如果我们将参数数量减少到 20 以下,它就可以工作。这是一个已知的问题?

这里是创建参数的代码:

    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

这是执行该过程的代码:

 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)

……

4

3 回答 3

2

这会让我感到惊讶,因为 20 并不是一个很高的数字,我认为你更有可能混淆了一些参数(当它超过 20 个时很容易做到)。

但是要尝试一下,我建议创建一个包含 21 个参数的过程,所有参数都是数字,然后将 1 发送给所有参数,这样您就可以确保它不仅仅是错误输入。

于 2010-04-28T18:10:59.083 回答
0

有两种调用 oracle 过程的方法。第一个是命名符号

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

第二个是定位

proc ('test', 1);

在命名表示法中,您可以按任何顺序放置参数并省略任何使用 DEFAULT 定义的参数。在位置表示法中,它们必须按照定义的顺序排列,只有最后一个可以省略。也就是说,如果您提供五个参数并且该过程定义了六个,那么它假定缺少的一个是第六个。同样,第六个必须有一个默认值。输出参数不能有默认值,必须提供。

我不确定 ODP 如何工作以选择使用哪个(尽管可以通过使用 DBMS_MONITOR 跟踪会话并查看生成的跟踪文件来确认)。

无论如何,请检查参数名称是否与您的代码中的名称匹配。除非引用,否则 Oracle 将标识符视为大写。此外,如果任何参数没有默认值,则必须在调用中设置它们(即使设置为 null)。

于 2010-04-28T23:09:59.433 回答
0

存储过程“LOADER.ADD_TARP_EVENT”将过程参数值默认为 Null(如果适用于服务器端)。当我们构建 ADO Oracle 命令时,我们没有填充 Null 参数,因为它们已经在过程中设置为默认为 Null。这与 ADO.NET 配合得很好。ODT 显然要求将值作为 dbNull 传入。一旦我们传入 dbNull 值,所有值都按预期工作。

于 2010-04-29T12:27:52.090 回答