2012-07-20 41 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提出的一些让我的语法问题突然出现的东西。