PLS-00306:錯誤解決思路 - OracleHelper 執行Oracle函數的坑


如果你是像我一樣初次使用Net+Oracle的結合,我想你會跟我一樣,有很大的概率碰到這個問題

=======================================================
PLS-00306: wrong number or types of arguments in call to '存儲過程名'
orA-06550: line 1, column 7:
PL/SQL: Statement ignored
=======================================================

或者說像這樣子的:

pls-00306 調用 時參數個數或類型錯誤


如果沒有經驗的話,就會一頭霧水到處亂撞。我也是被這個搞得很痛苦了,我把自己解決這問題思路與大家分享一下,希望能對您有所幫助.

Step1:確認你的Oracle包中的存儲過程中的參數的總數,是否與您在Net中調用存儲過程中的參數保持一致的數目。還有就是要注意function傳參與procedure傳參的參數的不同寫法.

function傳參的時候需要加入:號
例如:


Step2:確認你在Oracle包中的存儲過程的參數的數據類型,是否能與您在Net中調用存儲過程中的參數的數據類型匹配


Step3:確認你在Net應用程序中所使用的連接存儲過程和獲取返回值的方法是否正確..

這主要是在使用function的時候與使用procedure的時候,當需要獲取存儲過程或包中的返回的值的時候需要注意的不同方法.一般我們在獲取function的返回值的時候使用的是

new oracleParameter(":P_PRICEFORMID",OracleType.VarChar,20),
new oracleParameter(":P_VENDOR_CODE",OracleType.VarChar,20),
new oracleParameter(":P_VENDOR_SITE_CODE",OracleType.VarChar,20),
new oracleParameter(":P_VAT_CODE",OracleType.VarChar,20),
new oracleParameter(":P_ITEM_CODE",OracleType.VarChar,20),:

而使用procedure的時候是不用:號的


Step4:確認你所傳入Oracle中的各參數的值是否會出現null值.

在 傳入參數過多的時候,這里面的問題很難發現.只能通過一個一個值傳入去測試.所以最好的解決辦法是將所要傳入的參數都給定一個默認值,同時要注意數據類型 的匹配.盡量避免null值和空值的傳入. 有些情況下使用VS的斷點去追蹤,明明看見有值,可以在傳入oracle表內就會沒值,這種情況要特別注意.我就是碰到這樣的情況了.


Step5:確認你的服務器端Oracle版本是否與你在客戶端Oracle的版本保持一致.

有 些時候因為在不同的客戶端版本下所編譯的包的結果會有所差異,比如我在8i的情況下編譯通過,有可能在9i的版本就會通不過,這可能與pl/sql的語法 規定有關.所以盡量保持客戶端與服務器的oracle版本一致.最好的判斷辦法就是看看 sql plus的版本是否是一致.


我拿自己在實際過程中碰到的一個例子來說明吧.
見:
http://topic.csdn.net/u/20091019/00/8f05ee3b-e41c-4aff-bafd-a68d47f8eebf.html

我報的錯是這樣的:
報錯如下:

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

我的問題是:在本機上測試正常,放至服務器上就出現問題了.最終找到的根緣在於我有個字段傳了個null值或是沒有傳入值進入,導至報錯.我是一個一個字段去把這原因找出來的.雖說有點笨拙,但還是把問題給找出來了.




我的操作類中的方法:

這里要注意幾點的是:

1.要獲取包中存儲過程返回的值,需要這樣寫
parameters[13].Direction=ParameterDirection.Output;
2. 注意C#與Oracle的時間轉換 一般最好的解決方法是在C#中設置成string類型,然后在Oracle中通過to-date()函數把它轉化成時間格式.一開始我也是在這碰了個丁 子,后來通過在c#傳入所要的時間格式,在oracle中轉換成要用的時間格式即可.
parameters[5].Value = effectiveDate.ToString("yyyy-MM-dd hh:mm:ss");
要規定格式是因為考慮在服務器端是英文操作系統,所得到的默認時間格式與客戶端所提交的不同.所以需要根據服務器端的系統環境進行時間格式的設置.



///
        /// 插入已OK的價格至EBS中
        ///
        ///
        ///
        public bool InsertToEBS(Entity.CAS.PriceFormInfo priceForm)
        {
            oracleParameter[] parameters =
            {
                new oracleParameter("P_PRICEFORMID",OracleType.VarChar,20),
                new oracleParameter("P_VENDOR_CODE",OracleType.VarChar,20),
                new oracleParameter("P_VENDOR_SITE_CODE",OracleType.VarChar,20),
                new oracleParameter("P_VAT_CODE",OracleType.VarChar,20),
                new oracleParameter("P_ITEM_CODE",OracleType.VarChar,20),
                new oracleParameter("P_EFFECTIVE_DATE",OracleType.VarChar,20),
                new oracleParameter("P_PURCHASER",OracleType.VarChar,20),
                new oracleParameter("P_CHECKER",OracleType.VarChar,20),
                new oracleParameter("P_AUDITOR",OracleType.VarChar,20),
                new oracleParameter("P_POCT",OracleType.VarChar,10),
                new oracleParameter("P_UNIT_PRICE",OracleType.VarChar,20),
                new oracleParameter("P_PASSED_DATE",OracleType.VarChar,20),
                new oracleParameter("P_TERMS_DESC",OracleType.VarChar,100),
                new oracleParameter("v_retval",OracleType.Number)

            };


            parameters[0].Value = priceForm.FormID.ToString();
            parameters[1].Value = priceForm.SupplierCode;
            parameters[2].Value = priceForm.Vendor_site_code;
            parameters[3].Value = priceForm.Tax.ToString();
            parameters[4].Value = priceForm.MaterialCode.Trim();


            DateTime effectiveDate= Convert.ToDateTime(priceForm.EffectiveDate.ToString());

            DateTime passedDate= Convert.ToDateTime(priceForm.PassedDate.ToString());

        

            if (priceForm.EffectiveDate > priceForm.PassedDate)
            {


                parameters[5].Value = effectiveDate.ToString("yyyy-MM-dd hh:mm:ss");

          
            }
            else
            {
                parameters[5].Value = passedDate.ToString("yyyy-MM-dd hh:mm:ss");
            }
            parameters[6].Value = priceForm.Purchaser;
            parameters[7].Value = priceForm.Checker;
            parameters[8].Value = priceForm.Auditor;
            parameters[9].Value = priceForm.POCT;
            parameters[10].Value = priceForm.Price.ToString();
            parameters[11].Value = passedDate.ToString("yyyy-MM-dd hh:mm:ss");
            parameters[12].Value = priceForm.Payment.ToString().Trim();
            parameters[13].Direction=ParameterDirection.Output;

          

            try
            {
                Convert.ToInt32(OracleHelper.ExecuteNonQuery(OracleHelper.ConnectionStringProfile, CommandType.StoredProcedure, "PO_CAS_PRICE_PKG.InsertToEBSCode", parameters));

                int retval = Convert.ToInt32(parameters[13].Value);

                if (retval == 1)
                {
                    return true;
                }
                else

                    return false;
            }
            catch (Exception ee)
            {
                throw ee;
            }
            finally
            {

            }

包中的存儲過程
中的存儲過程:

create or replace package PO_CAS_PRICE_PKG is

  -- Author  : EASTJAZZ
  -- Created : 2009-10-16 0:29:13
  -- Purpose :

  procedure InsertToEBSCode(P_PRICEFORMID      IN VARCHAR2,
                            P_VENDOR_CODE      IN VARCHAR2,
                            P_VENDOR_SITE_CODE IN VARCHAR2,
                            P_VAT_CODE        IN VARCHAR2,
                            P_ITEM_CODE        IN VARCHAR2,
                            P_EFFECTIVE_DATE  in VARCHAR2,
                            P_PURCHASER        IN VARCHAR2,
                            P_CHECKER          IN VARCHAR2,
                            P_AUDITOR          IN VARCHAR2,
                            P_POCT            IN VARCHAR2,
                            P_UNIT_PRICE      IN VARCHAR2,
                            P_PASSED_DATE      IN VARCHAR2,
                            P_TERMS_DESC      IN VARCHAR2,
                            v_retval          out number);

end PO_CAS_PRICE_PKG;


調用函數取得返回值的Example


public string GetItemDescription(string item_code, int org_id)
       {
           oracleParameter[] Parms =
           {
              
               new oracleParameter("p_item_code",OracleType.VarChar,20),
               new oracleParameter("p_org_id",OracleType.Number,4),
               new oracleParameter("v_item_desc",OracleType.VarChar,150)
           };

           Parms[0].Value = item_code;
           Parms[1].Value = org_id;
           Parms[2].Direction = ParameterDirection.ReturnValue;


           IList vendorItemList = new List();

           oracleHelper.ExecuteNonQuery(OracleHelper.ConnectionStringProfile, CommandType.StoredProcedure, "PO_VENDORS_PKG.GetItemDescription", Parms);

         return Parms[2].Value.ToString().Trim();
       }



Function:

  function GetItemDescription(p_item_code in varchar2, p_org_id number)
    return varchar2 is
    v_item_desc varchar2(150);
  begin
  
    select msib.DESCRIPTION item_desc
      into v_item_desc
      from MTL_SYSTEM_ITEMS_B msib
    
     where msib.SEGMENT1 = trim(p_item_code)
       and msib.ORGANIZATION_ID = p_org_id;
  
    return v_item_desc;
  
  end GetItemDescription;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM