2012-04-13 53 views
1

請耐心等待下面我要寫的代碼。我有2種方法:添加了OracleCommand參數,但拋出了異常

 public void AddInParameters(string parameterName, OracleDbType dbtype, 
                   object value) 
    { 
     OracleParameter myparameter = new OracleParameter(); 
     myparameter.ParameterName = parameterName; 
     myparameter.OracleDbType = dbtype; 
     myparameter.Value = value; 
     myparameter.Direction = ParameterDirection.Input; 
     this._parameters.Add(myparameter); 
    } 

public void AddOutParameter(string parameterName, OracleDbType dbType) 
    { 
     OracleParameter myparameter = new OracleParameter(); 
     myparameter.ParameterName = parameterName; 
     myparameter.OracleDbType = dbType; 
     myparameter.Direction = ParameterDirection.Output; 
     this._parameters.Add(myparameter); 
    } 

私人領域_parameters的類型是List。正如你所看到的,這些方法分別創建Input和Output參數並將它們添加到_parameters列表中。然後,我有以下方法,將採取的OracleCommand和列表中的所有參數添加到它:

 private void ProcessParameters(OracleCommand command) 
    { 
     foreach (OracleParameter myparameter in this._parameters) 
     { 
      command.Parameters.Add(myparameter); 
     } 
    } 

這是我的一個返回OracleDataReader最後一個方法:

public OracleDataReader ExecuteReader(string commandText, CommandType commandType) 
    { 
     OracleDataReader returnValue = null; 
     OracleCommand myCommand = this.CreateCommand(commandText, commandType); 
     this.ProcessParameters(myCommand); 
     try 
     { 

      myCommand.Connection.Open(); 
      returnValue = myCommand.ExecuteReader(CommandBehavior.CloseConnection); 
     } 
     catch (Exception ex) 
     { 

      throw new DatabaseException(ex.Message); 
     } 


     return returnValue; 

    } 

所有這些方法在數據訪問層類庫中。當我想打電話給ExcuteReader方法我做以下步驟,以便類:

  1. 我第一次使用AddInParameters和AddOutparameters
  2. 然後我打電話ExecuteReader方法添加參數。

但我有時會得到「錯誤的數字或類型的參數」Oracle異常。如果我拒絕使用這些方法,請繼續使用標準方式(創建連接,然後是命令,然後逐個添加參數,打開連接並最終調用OracleCommand.ExecuteReader方法)。我不會收到該錯誤。奇怪的是,我在應用程序的入口處使用了這些方法,但我從來沒有得到任何異常。在ExecuteReader方法的執行之前,我放置了一個斷點來檢查參數列表,所有東西都很好,我的意思是所有參數都設置正確。你能否告訴我我在這裏失去了什麼?

P.S.我使用Oracle的Oracle數據提供程序(Oracle.Data.Access.dll)。

+0

這裏閱讀:http://forums.asp.net/t/606602.aspx/1 – 2012-04-13 05:18:52

回答

2

真的覺得很好,找到解決問題的方法花了我1.5天。正如我已經說過的,甲骨文真的很頭疼。這就像一個「我不想要這個,我不想要這個,我想要這樣」的女孩。如此多的細節,需要考慮的東西太多了。那些對甲骨文瘋狂的人說,這就是Oracle強大的原因。

經過漫長的戰鬥和無望的搜索@ Dummy01建議我設置OracleCommand.BindByName = true。我其實並沒有立即嘗試。我擡頭一看是ODP.NET文檔中的財產,並期待什麼,我發現:

如果的OracleCommand BindByName屬性設置爲false(默認值),然後 ODP.NET假設參數已經基於約束自己位置和 所有參數都按正確的順序指定。

所以這意味着,如果在存儲過程中參數按照p1,p2,p3的順序,則必須按照相同順序將這些參數添加到OracleCommand.Parameters中。否則可能發生兩件不好的事情:

  1. 最好的情況是你得到例外。假設你按照p1,p3,p2的順序傳遞它們,p2是類型編號,p3是一個refcursor。數據庫中的存儲過程期望第二個參數是一個數字,第三個參數是refcursor。但是,由於參數傳遞的順序與原始傳遞的順序不同,這些類型將不兼容,因此會引發異常。如果這些類型不同,你很幸運。
  2. 第二個也是最壞的情況是p2和p3都是相同的數據類型。我相信你可以猜到會發生什麼:是的,你會爲參數輸入錯誤的值,這將導致99%的結果與預期不同。

    我希望任何處理Oracle存儲過程的人都會考慮到這一點,否則他們可能會失去工作。祝你好運

3

您是否嘗試過使用OracleCommand.BindByName = true

+0

是的,它的工作後,我想你suggested.You是一個生命的救星。我會根據你給出的提示,對我的問題寫一個詳細的答案。萬分感謝。 – 2012-04-13 06:37:51

+0

@Mike JM很高興我幫你。請記住儘可能接受你喜歡的答案。 – Dummy01 2012-04-13 06:43:39