我正在尝试将一个Oracle数据库与ado.net一起使用,这证明是一种痛苦的经历。我使用Oracle Client(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,keyword,value)上运行其他查询时,这甚至更加奇怪 - 并且它们可以在没有打嗝的情况下工作。
对于记录,列类型为requestID NUMBER(10,0); key VARCHAR2(30);值VARCHAR2(2000)。
根据Oracle,ORA-01722'无效数字'表示字符串无法转换为数字。我的字符串值都不是数字,为它们创建的OracleParameters都不是数字,也不是
答案 0 :(得分:4)
默认情况下,ODP.NET按位置绑定参数,而不是按名称绑定,即使它们在SQL中有实际名称(而不仅仅是?)。因此,您实际上将 requestID 绑定到:value , key 到:requestID 和 value to :key 。
更正代码中cmd.Parameters.Add
的顺序,或使用BindByName告诉ODP.NET使用参数名称。
答案 1 :(得分:3)
由于您使用的是命名参数,因此您必须告诉Oracle客户端。否则,您的参数会混淆(键分配给:值):
OracleParameter parameter = new OracleParameter("requestID", (long)1);
parameter.BindByName = true;
cmd.Parameters.Add(parameter);
这是一种奇怪而意外的行为,但事实就是如此。