2012-07-20 65 views
0

我有一個存儲過程可以正常工作,並且在插入數據時一直工作數月。Oracle ArrayBound存儲過程僅在特定字段中失敗

這裏的「短」版:

procedure saveApplication( in_confirmation_number varchar2 := null       
          ,in_nonstandard_address varchar2 := null  
          ,in_absentee_type varchar2 := null) AS 
    BEGIN 
    insert into vr_application (
      confirmation_number 
      ,nonstandard_address 
      ,absentee_type) 
    values (in_confirmation_number 
      ,in_nonstandard_address 
      ,in_absentee_type 
      ); 
END; 

我在批量工作,所以我從一個DataTable拉動值之後的東西,在作爲陣列中的數據。 再次,下面是「縮短」版本。

private static void loadFiles(DataTable dt, string connString, ErrorLogger log) 
    { 

     OracleConnection orclconn = null; 
     OracleCommand cmd = null; 

     using (orclconn = new OracleConnection(connString)) 
     { 
      orclconn.Open(); 
      using (cmd = BuildCommand(dt)) 
      { 
       cmd.Connection = orclconn; 
       cmd.ExecuteNonQuery(); 
      } 
     } 

    } 

private static OracleCommand BuildCommand(DataTable dt) 
    { 
     OracleCommand cmd = new OracleCommand(); 
     cmd.CommandText = "Applications.saveApplication"; 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.ArrayBindCount = dt.Rows.Count; 
     cmd.BindByName = true; 

     string[] CONFIRMATION_NUMBER = dt 
      .AsEnumerable() 
      .Select(row => row.Field<string>("CONFIRMATION_NUMBER")) 
      .ToArray(); 
     OracleParameter in_confirmation_number = new OracleParameter(); 
     in_confirmation_number.OracleDbType = OracleDbType.Varchar2; 
     in_confirmation_number.Value = CONFIRMATION_NUMBER; 
     in_confirmation_number.ParameterName = "in_confirmation_number"; 
     cmd.Parameters.Add(in_confirmation_number); 

     string[] ABSENTEE_TYPE = dt 
      .AsEnumerable() 
      .Select(row => row.Field<string>("ABSENTEE_TYPE")) 
      .ToArray(); 
     OracleParameter in_absentee_type = new OracleParameter(); 
     in_absentee_type.OracleDbType = OracleDbType.Varchar2; 
     in_absentee_type.Value = ABSENTEE_TYPE; 
     in_absentee_type.ParameterName = "in_absentee_type"; 
     cmd.Parameters.Add(in_absentee_type); 

     string[] NONSTANDARD_ADDRESS = dt 
     .AsEnumerable() 
     .Select(row => row.Field<string>("NONSTANDARD_ADDRESS")) 
     .ToArray(); 
     OracleParameter in_nonstandard_address = new OracleParameter(); 
     in_absentee_type.OracleDbType = OracleDbType.Varchar2; 
     in_absentee_type.Value = NONSTANDARD_ADDRESS; 
     in_absentee_type.ParameterName = "in_nonstandard_address"; 
     cmd.Parameters.Add(in_nonstandard_address); 

     return cmd; 
} 

方案1: nonstandard_address代碼註釋。一切正常。

場景2: nonstandard_address代碼沒有被註釋掉。但不是將值傳遞到原始數據表中,而是將值「硬編碼爲」空值「。一切正常。這是幾個月以來的情況。

場景3: 非標準地址的數據表有一個非標準地址的單個行。該列的所有其他行都包含空值。我得到一個Oracle.DataAccess.Client.OracleException,#ORA-06550,帶有消息「遇到符號」>「當期待以下某項時......」

爲了試圖找出問題,我簡單地遍歷數組中的值。在最後一個循環迭代中,我得到的錯誤總是比數據表(100)中的記錄數多一個。但是如果我循環而不嘗試創建一個非標準的Oracle參數,我沒有錯誤,只有100個循環迭代。

如果我做了方案2併成功地填充了除nonstandard_address以外的所有表,我可以在Oracle中運行以下代碼,併成功更新表。

update vr_application a 
set nonstandard_address = (select nonstandard_address from unprocessed_apps b where b.confirmation_number = a.confirmation_number) 
where exists (select 1 from unprocessed_apps where confirmation_number = a.confirmation_number) 

任何人都可以在這裏看到一個錯誤嗎?任何人見過這個?我很困惑。

+1

嘗試在absentee_type的代碼之前放置nonstandard_address參數的代碼,以便按照它們在PL/SQL過程中命名的順序指定參數。我認爲這不重要,但值得一試。值得一試的 – 2012-07-21 01:33:41

+0

- 我將在今天晚些時候處理這​​個問題,並讓您知道結果。 – user158017 2012-07-21 11:48:22

+0

移動它不是答案,但它給了我一個編譯錯誤的答案。現在我感到很蠢。但我猜想在更新72場後,眼睛變得模糊不清。看看我的變量名 - 我用in_absentee_type作爲變量來接收非標準地址。這當然意味着價值不適合現場。Oracle錯誤有點讓人誤解。感謝您讓我找到正確的解決方案! – user158017 2012-07-21 15:49:57

回答

0

嗯,這是那些「嘟嘟嘟嘟」的時刻之一,也是讓同事們可以成爲額外眼睛的好主意。

看看我的代碼 - 我將地址填入缺席字段。這是我有:

string[] NONSTANDARD_ADDRESS = dt 
    .AsEnumerable() 
    .Select(row => row.Field<string>("NONSTANDARD_ADDRESS")) 
    .ToArray(); 
    OracleParameter in_nonstandard_address = new OracleParameter(); 
    **in_absentee_type**.OracleDbType = OracleDbType.Varchar2; 
    **in_absentee_type**.Value = NONSTANDARD_ADDRESS; 
    **in_absentee_type**.ParameterName = "in_nonstandard_address"; 
    cmd.Parameters.Add(in_nonstandard_address); 

這是我應該有:

 string[] NONSTANDARD_ADDRESS = dt 
      .AsEnumerable() 
      .Select(row => row.Field<string>("NONSTANDARD_ADDRESS")) 
      .ToArray(); 
     OracleParameter in_nonstandard_address = new OracleParameter(); 
     **in_nonstandard_address**.OracleDbType = OracleDbType.Varchar2; 
     **in_nonstandard_address**.Value = NONSTANDARD_ADDRESS; 
     **in_nonstandard_address**.ParameterName = "in_nonstandard_address"; 
     cmd.Parameters.Add(in_nonstandard_address); 

72個陣列像上面盯着後,我的眼睛只是完全錯過了它。感謝Bob Jarvis提出的一些讓我的語法問題突然出現的東西。