簡體   English   中英

如何使用ODP.Net向存儲過程發送20多個參數?

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

從Microsoft的Oracle驅動程序切換到ODP.NET版本10.2.0.100。 在使用System.Data.OracleClient正常運行的過程中將數據類型更改為OracleDBTypes之后,如果嘗試傳遞20個以上的參數,則過程將失敗。 返回的錯誤是:

ORA-06550:第1行,第7列:PLS-00306:調用“ ADD_TARP_EVENT”時參數的數量或類型錯誤ORA-06550:第1行,第7列:PL / SQL:語句被忽略

如果我們將參數數量減少到少於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)

....

因為20的數字不是一個很高的數字,這會讓我感到驚訝,我認為您更有可能混入一些參數(當超過20個時,很容易做到)。

但是要嘗試一下,我建議創建一個包含21個參數的過程,所有參數均為數字,然后將1發送給所有參數,這樣就可以確保它不僅是一個錯誤的類型。

有兩種方法可以調用oracle過程。 第一個是命名法

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

第二個是位置

proc ('test', 1);

在命名符號中,您可以按任何順序放置參數,並忽略使用DEFAULT定義的任何參數。 在位置表示法中,它們必須按照定義的順序,並且只能省略最后一個。 也就是說,如果您提供五個參數,並且該過程定義了六個,則假定缺少的一個是第六個。 同樣,第六個必須具有默認值。 輸出參數不能具有默認值,必須提供。

我不確定ODP如何選擇使用哪個(盡管可以通過使用DBMS_MONITOR跟蹤會話並查看生成的跟蹤文件來確認)。

無論如何,請檢查參數名稱是否與代碼中的名稱匹配。 除非加引號,否則Oracle將標識符視為大寫。 另外,如果任何參數沒有默認值,則必須在調用中進行設置(即使設置為null)。

存儲過程“ LOADER.ADD_TARP_EVENT”在服務器端適用的情況下,將過程參數值默認為Null。 在構建ADO Oracle Command時,我們沒有填充Null參數,因為在該過程中已經將它們設置為默認值。 這對於ADO.NET效果很好。 ODT顯然要求將值作為dbNull傳入。 一旦我們為所有值傳遞dbNull,它們都將按預期工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM