10

我一直在使用参数化查询将值插入到 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 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;
4

3 回答 3

49

我已经给出了答案,但我认为这里值得一提的是我的问题的根源是什么,以防其他人在寻找自己问题的答案时发现了这个项目。

问题在于,Oracle 参数化查询的 C# 实现包含一个严重且具有潜在危险的错误 - 一个真正的“公共领域的坑”:

给参数起什么名字并不重要。它们必须按照它们在查询中出现的顺序添加。

在这里查看更多。

于 2010-10-06T21:51:19.737 回答
5

当您说您检查了参数时,您的意思是ParametersSqlCommand 类上的集合吗?您可能会在 SqlParameter 页面上遇到此注释

使用 SqlParameter 构造函数的此重载来指定整数参数值时要小心。由于此重载采用 Object 类型的值,因此必须在值为零时将整数值转换为 Object 类型,如以下 C# 示例所示。复制

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

如果您不执行此转换,编译器会假定您正在尝试调用 SqlParameter (string, SqlDbType) 构造函数重载。

我建议你使用类似的东西

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

而是显式设置类型。

于 2010-10-05T17:55:05.053 回答
1
command.BindByName = true;

请看这个解释。

于 2016-08-26T15:49:56.793 回答