简体   繁体   English

为什么我会收到 ORA-01722(无效号码)?

[英]Why am I getting an ORA-01722 (invalid number)?

I've been using a parameterized query to insert values into an Oracle table, like so:我一直在使用参数化查询将值插入到 Oracle 表中,如下所示:

var q = "insert into MyTable(Field1, Field2...) values(:Field1, :Field2...)";
var cmd = new OracleCommand(q, conn); // conn is a pre-existing connection
cmd.Parameters.Add("Field1", field1Val); 
cmd.Parameters.Add("Field2", field2Val);
// etc...
cmd.ExecuteNonQuery();

This has been working fine, but suddenly this has stopped working, and I am getting Oracle error ORA-01722 (invalid number).这一直工作正常,但突然停止工作,我收到 Oracle 错误 ORA-01722(无效数字)。 I have checked the parameters, and all numbers are unquestionably valid numbers.我检查了参数,所有数字都是毫无疑问的有效数字。 I even substituted dummy values for any nulls, and I still get the error.我什至用虚拟值替换了任何空值,但仍然出现错误。 I tried the same query in direct sql (using OraDeveloper Studio), and it works, even with the identical parameters.我在直接 sql(使用 OraDeveloper Studio)中尝试了相同的查询,即使使用相同的参数,它也能工作。

How do I track this one down?我如何追踪这个?

EDIT: per request in the comments, here's the create table statement:编辑:根据评论中的请求,这是创建表语句:

CREATE TABLE ALPHA.VISITFINDINGS (
  ID NUMBER(12),
  VISITID NUMBER(12) NOT NULL,
  DESCRIPTION VARCHAR2(100),
  CUSTOMIMAGE CLOB,
  VISUALFINDINGSSECTIONMAPID NUMBER(12),
  FINDINGSID NUMBER(12),
  CONSTRAINT FK_VISITFINDINGS_AREA FOREIGN KEY (VISUALFINDINGSSECTIONMAPID)
    REFERENCES ALPHA.VISUALFINDINGSSECTIONMAP(VISUALFINDINGSSECTIONMAPID),
  CONSTRAINT FK_VISITFINDINGS_FINDINGS FOREIGN KEY (FINDINGSID)
    REFERENCES ALPHA.FINDINGS(FINDINGSID),
  CONSTRAINT FK_VISITFINDINGS_VISIT FOREIGN KEY (VISITID)
    REFERENCES ALPHA.VISITS(VISITID),
  CONSTRAINT PK_VISITFINDINGS PRIMARY KEY (ID))
TABLESPACE USERS
STORAGE (
  INITIAL 64K
  MAXEXTENTS UNLIMITED
)
LOGGING;

I have given answer credit already, but I think it's worth mentioning here exactly what the root of my problems was, in case anyone else finds this item while looking for an answer to their own problem.我已经给出了答案,但我认为这里值得一提的是我的问题的根源是什么,以防其他人在寻找自己问题的答案时找到了这个项目。

The problem is that the C# implementation of parameterized queries for Oracle contains a serious and potentially dangerous bug - a real "pit in the public domain":问题在于,Oracle 参数化查询的 C# 实现包含一个严重且具有潜在危险的错误 - 一个真正的“公共领域的坑”:

It doesn't matter what you name your parameters;参数的名称无关紧要; they have to be added in the order in which they appear in the query.它们必须按照它们在查询中出现的顺序添加。

See more here . 在此处查看更多信息

When you say you checked the parameters do you mean the Parameters collection on the SqlCommand class?当您说您检查了参数时,您的意思是 SqlCommand 类上的Parameters集合吗? You might be falling foul of this note on the SqlParameter page :您可能会在 SqlParameter 页面上与此注释发生冲突

Use caution when you use this overload of the SqlParameter constructor to specify integer parameter values.使用 SqlParameter 构造函数的此重载指定整数参数值时要小心。 Because this overload takes a value of type Object, you must convert the integral value to an Object type when the value is zero, as the following C# example demonstrates.由于此重载采用 Object 类型的值,因此当该值为零时,您必须将整数值转换为 Object 类型,如以下 C# 示例所示。 Copy复制

Parameter = new SqlParameter("@pname", Convert.ToInt32(0));

If you do not perform this conversion, the compiler assumes that you are trying to call the SqlParameter (string, SqlDbType) constructor overload.如果不执行此转换,编译器会假定您正在尝试调用 SqlParameter (string, SqlDbType) 构造函数重载。

I'd suggest you use something like我建议你使用类似的东西

cmd.Parameters.Add(
   new SqlParameter("Field1", SqlDbType.Int32) { Value = field1Val });

instead to explicitly set the type.而是显式设置类型。

command.BindByName = true;

请看这个解释

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM