Oracle ArrayBound存储过程仅对特定字段失败

时间:2012-07-20 23:42:33

标签: c# .net oracle ado.net odp.net

我有一个可以使用的存储过程,并且已经工作了好几个月来插入数据。

这是“简短”版本:

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;

我正在批量工作,因此在从数据表中提取值后,我将数据填入数组中。 同样,下面是“缩短版”。

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代码未注释掉。但是不是将值传递到原始数据表中,而是将值硬编码为“null”。一切正常。这已经好几个月了。

场景3: 非标准地址的数据表有一行,其值在非标准地址中。此列的所有其他行都包含null。我得到一个Oracle.DataAccess.Client.OracleException,#ORA-06550,消息“遇到了符号”&gt;“当期待以下之一时....”

为了尝试识别问题,我只是循环遍历数组中的值。我在最后一次循环迭代中得到相同的错误,它总是比数据表(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 个答案:

答案 0 :(得分: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)提出的建议使我的语法问题突然出现的事情。