我一直在使用参数化查询将值插入到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();
这一直运行良好,但突然之间已停止工作,我收到Oracle错误ORA-01722(无效数字)。我检查了参数,所有数字无疑都是有效的数字。我甚至为任何空值替换了虚拟值,我仍然得到错误。我在直接sql(使用OraDeveloper Studio)中尝试了相同的查询,即使使用相同的参数,它也能正常工作。
如何跟踪这个?
编辑:评论中的每个请求,这是create table语句:
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;
答案 0 :(得分:38)
我已经给出了答案信用,但我认为在这里确切地提到问题的根源是什么,以防其他人在寻找他们自己问题的答案时找到这个项目。
问题是Oracle的参数化查询的C#实现包含一个严重且有潜在危险的错误 - 一个真正的“公共领域”:
您的参数名称无关紧要;它们必须按照它们在查询中出现的顺序添加。
查看更多here。
答案 1 :(得分:5)
当您说您检查了参数时,您是指SqlCommand类上的Parameters
集合吗?你可能会对this note on the SqlParameter page犯下错误:
使用SqlParameter构造函数的此重载指定整数参数值时请小心。因为此重载采用Object类型的值,所以当值为零时,必须将整数值转换为Object类型,如下面的C#示例所示。 复制
Parameter = new SqlParameter("@pname", Convert.ToInt32(0));
如果不执行此转换,编译器会假定您正在尝试调用SqlParameter(string,SqlDbType)构造函数重载。
我建议您使用类似
的内容cmd.Parameters.Add(
new SqlParameter("Field1", SqlDbType.Int32) { Value = field1Val });
而是明确设置类型。
答案 2 :(得分:1)
command.BindByName = true;
请参阅此explination.