ORA-01400 无法插入空值...但我没有插入空值!

发布于 2024-10-22 05:23:14 字数 1613 浏览 5 评论 0原文

我尝试使用 C# 应用程序中的 ODP.NET 在 Oracle 表中插入数据,但对于我不在其中的列,出现 ORA-01400 无法插入空值 错误插入空值。

这是我尝试执行的参数化 SQL 命令的精简版本。它包装在 OracleCommand 中,并通过调用 ExecuteNonQuery 来执行:

declare c int; 
begin
   select count(*) into c from "Entradas" where "Id" = :Id and nvl("AppId", 0) = nvl(:AppId, 0);
   if c>0 then
       update "Entradas" set
         /*...a bunch of columns...*/,
         "VisitaLaboral" = :VisitaLaboral,
         /*...some more columns...*/
         where "Id" = :Id and nvl("AppId",0) = nvl(:AppId, 0); 
   else
       insert into "Entradas" (
         /*... a bunch of columns...*/,
         "VisitaLaboral",
         /*...some more columns...*/
         ) values (
         /*...a bunch of values...*/,
         :VisitaLaboral,
         /*...some more values...*/
       );
   end if;
end;

该行以前不存在,因此它是命令的 insert 部分被执行的那个。当然,我已经验证了所有列名和列值参数都正确放置在 SQL 文本中。

问题出在 VisitaLaboral 列中。它的类型为 NUMBER(1,0),它不接受 NULL,并且我尝试插入值 0。这是 Visual Studio 在命令执行之前立即显示的有关关联 OracleParameter 的内容:

在此处输入图像描述

但是,如果我直接在 Application Express 中执行命令(直接在命令文本中提供值),它工作正常并且该行已插入。

那么,这里发生了什么? ODP.NET 库中是否存在错误,或者我做错了什么?

附加信息:

  • 数据库是 Oracle 10g Express Release 10.2.0.1.0
  • Oracle.DataAccess.dll 版本是 4.112.1.2
  • 使用 Visual Studio 2010,针对 .NET Framework 4.0

预先感谢您!

更新:

如果我使用(已弃用的)System.Data.OracleClient 类而不是 ODP.NET,则一切正常。

WTF,甲骨文?不,真的,WTF?

I am trying to insert data in an Oracle table by using ODP.NET from a C# application, but I am getting an ORA-01400 can't insert null value error for a column in which I am NOT inserting a null value.

This is the stripped down version of the parametrized SQL command I am trying to execute. It is wrapped in an OracleCommand and executed with an invokation of ExecuteNonQuery:

declare c int; 
begin
   select count(*) into c from "Entradas" where "Id" = :Id and nvl("AppId", 0) = nvl(:AppId, 0);
   if c>0 then
       update "Entradas" set
         /*...a bunch of columns...*/,
         "VisitaLaboral" = :VisitaLaboral,
         /*...some more columns...*/
         where "Id" = :Id and nvl("AppId",0) = nvl(:AppId, 0); 
   else
       insert into "Entradas" (
         /*... a bunch of columns...*/,
         "VisitaLaboral",
         /*...some more columns...*/
         ) values (
         /*...a bunch of values...*/,
         :VisitaLaboral,
         /*...some more values...*/
       );
   end if;
end;

The row does not exist previously so it is the insert part of the command the one that is executed. Of course I have verified that all the column names and column value parameters are properly placed in the SQL text.

The problem is in the VisitaLaboral column. It is of type NUMBER(1,0), it does not accept NULLs, and I am trying to insert a value of 0. This is what Visual Studio displays about the associated OracleParameter immediately before the command execution:

enter image description here

However if I execute the command directly in Application Express (providing the values directly in the command text), it works fine and the row is inserted.

So, what is happening here? Is there a bug in the ODP.NET library, or am I doing something wrong?

Additional information:

  • Database is Oracle 10g Express Release 10.2.0.1.0
  • Oracle.DataAccess.dll version is 4.112.1.2
  • Using Visual Studio 2010, targeting .NET framework 4.0

Thank you in advance!

UPDATE:

Everything works fine if I use the (deprecated) System.Data.OracleClient classes instead of ODP.NET.

WTF, Oracle? No, really, WTF?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夜唯美灬不弃 2024-10-29 05:23:14

您的问题似乎是您不知道数据库中实际发生了什么。最快的解决方案是找出发生的情况并加以利用。

  1. 连接到数据库
  2. 使用 dbms_session.set_sql_trace(true) 启用 sql 跟踪
  3. 您的应用程序操作是否
  4. 与数据库断开连接
  5. 查找 - 或询问您的 dba - 向您发送原始跟踪文件

在跟踪文件(纯文本文件)中查找您的代码并查看引发错误时会发生什么。

可能是扳机被触发了......

Your problem seems to be that you don't know what is actually happening in the database. The quickest solution will be to find out what happens and use that.

  1. connect to the database
  2. use dbms_session.set_sql_trace(true) to enable an sql trace
  3. do your application action
  4. disconnect from the database
  5. find - or ask your dba - to send you the raw trace file

In the tracefile (a plain text file) find your code and see what happens when the error is raised.

It could be that a trigger fired ....

甜心 2024-10-29 05:23:14

这是数据库级别的错误消息,您可以确定插入有空值。是否可以注销ODP.NET生成的sql语句?

This is a DB level error message, you can be sure that the insert has null value. Is it possible to log out the sql statement generated by the ODP.NET?

祁梦 2024-10-29 05:23:14

您真的确定插入子句和值子句中的列顺序相同吗?检查你的“一堆列”......

Are you really really sure that you have the columns in the same order on both the insert clause and the values clause? Check your "bunch of columns" ...

勿挽旧人 2024-10-29 05:23:14

好吧,我对 ODP.net 一无所知,但是如果参数中有一个值,那么精度、比例和大小属性是否都应该为零(就像它们看起来的那样)?

Well I know nothing about ODP.net, but if there is a value in the parameter, should the precison, scale and size attributes all be zero (as they appear to be)?

┾廆蒐ゝ 2024-10-29 05:23:14

我们有同样的问题。我们解决了将列属性“IsNullable”设置为 true 的问题。

We had the same problem. We solved the problem setting column property "IsNullable" to true.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文