我有一个存储过程可以正常工作,并且在插入数据时一直工作数月。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)
任何人都可以在这里看到一个错误吗?任何人见过这个?我很困惑。
尝试在absentee_type的代码之前放置nonstandard_address参数的代码,以便按照它们在PL/SQL过程中命名的顺序指定参数。我认为这不重要,但值得一试。值得一试的 – 2012-07-21 01:33:41
- 我将在今天晚些时候处理这个问题,并让您知道结果。 – user158017 2012-07-21 11:48:22
移动它不是答案,但它给了我一个编译错误的答案。现在我感到很蠢。但我猜想在更新72场后,眼睛变得模糊不清。看看我的变量名 - 我用in_absentee_type作为变量来接收非标准地址。这当然意味着价值不适合现场。Oracle错误有点让人误解。感谢您让我找到正确的解决方案! – user158017 2012-07-21 15:49:57