2

我正在尝试将 Oracle 数据库与 ado.net 一起使用,但事实证明这是一次痛苦的经历。我使用 Oracle 客户端(Oracle.Data 命名空间)。

以下查询在查询窗口中运行良好:

UPDATE PRINT_ARGUMENT SET VALUE = 'Started' WHERE REQUEST_ID = 1 AND KEYWORD = '{7D066C95-D4D8-441b-AC26-0F4C292A2BE3}'

但是,当我创建 OracleCommand 时,ORA-01722 也会发生同样的事情。我不知道为什么。

var cmd = cnx.CreateCommand();
cmd.CommandText = @"
UPDATE PRINT_ARGUMENT
SET VALUE = :value 
WHERE REQUEST_ID = :requestID AND KEYWORD = :key";

cmd.Parameters.Add(new OracleParameter("requestID", (long)1); cmd.Parameters.Add(new OracleParameter("key", "{7D066C95-D4D8-441b-AC26-0F4C292A2BE3}"); cmd.Parameters.Add(new OracleParameter("value", "Started");

cnx.Open(); try { int affected = cnx.ExecuteNonQuery(); } finally { cnx.Close(); }

当我在调试器中检查命令时,参数似乎已映射到正确的类型:requestID 具有 OracleDbType.Int64,键和值都是 OracleDbType.Varchar2。参数的也是正确的。

当您考虑到我有其他查询使用相同的方法对完全相同的列(requestID、关键字、值)进行操作时,这就变得更加奇怪了——而且它们工作起来没有问题。

对于记录,列类型为 requestID NUMBER(10,0);键 VARCHAR2(30); 值 VARCHAR2(2000)。

根据 Oracle 的说法,ORA-01722 'invalid number' 意味着字符串无法转换为数字。我的字符串值都不是数字,为它们创建的 OracleParameters 都不是数字,也不是

4

2 回答 2

4

默认情况下,ODP.NET按位置而不是名称绑定参数,即使它们在 SQL 中有实际名称(而不仅仅是?)。因此,您实际上是将requestID绑定到:value,将key绑定到: requestID,将value绑定到:key

更正cmd.Parameters.Add代码中的顺序,或使用BindByName告诉 ODP.NET 使用参数名称。

于 2011-11-14T12:18:02.917 回答
3

由于您使用的是命名参数,因此您必须将其告知 Oracle 客户端。否则您的参数会混淆(分配给:value):

OracleParameter parameter = new OracleParameter("requestID", (long)1);
parameter.BindByName = true;
cmd.Parameters.Add(parameter);

这是一种奇怪且出乎意料的行为,但事实就是如此。

于 2011-11-14T11:53:25.720 回答