2011-03-16 118 views
3

我想通过使用ODP.NET从一个C#应用程序中插入数据在Oracle表中,但我得到一个ORA-01400不能插入空值错误的列,其中我不插入空值。ORA-01400不能插入空值...但我不插入空值!

这是我尝试执行的参数化SQL命令的精简版本。它被包裹在一个OracleCommand并用的ExecuteNonQuery一个invokation执行:

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),它不接受空值,和我试图插入值0。这是怎么样的相关OracleParameter立即命令执行之前的Visual Studio显示:

enter image description here

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

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

其他信息:

  • 数据库是Oracle 10g快捷版10.2.0.1.0
  • Oracle.DataAccess.dll版本是4.112.1.2
  • 使用Visual Studio 2010中,针对.NET框架4.0

预先感谢您!

更新:如果我使用的,而不是ODP.NET的(不建议使用)System.Data.OracleClient

,一切工作正常。

WTF,Oracle?不,真的,WTF?

+0

我不知道,但也许[这个问题](http://stackoverflow.com/questions/4863960/could-somebody-explain-what- merge-statement-really-in-oracle)可能会让你感兴趣。 – Benoit 2011-03-16 09:47:02

+0

你可以发布.net代码吗? – Harrison 2011-03-16 12:00:11

+0

是否在ODP中尝试了“command.bindbyname = True”(默认情况下System.Data.OracleClient按名称绑定,而默认情况下按位置绑定ODP)。试试bindbyname = true,看看会发生什么 – Harrison 2011-03-16 12:52:34

回答

0

你真的确定你在insert子句和values子句中都有相同顺序的列吗?检查你的“一堆列”...

+0

这是我第一次仔细检查。一切似乎都在正确的地方。 – Konamiman 2011-03-16 10:02:39

+0

@konaniman,我同意@Stefan在这里,我会建议您将命令对象上的bindbyname设置为true [command.bindbyname = True],确保命令参数中的名称与匿名块匹配,那么您将不需要担心秩序。这些问题通常与param命令问题有关。 – Harrison 2011-03-16 11:58:58

1

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

+0

Is是一个OracleCommand.ExecuteNonQuery调用,所以除非我缺少一些东西,否则ODP.NET不会生成任何SQL语句,因为我直接提供它。无论如何,我怎么能配置这种日志记录? – Konamiman 2011-03-16 10:04:43

0

那么我对ODP.net一无所知,但是如果参数中有一个值,那么precod,scale和size属性应该都为零(因为它们看起来像是)?

+0

好主意,但将Precision设置为1(该列具有精度1和等级0)不起作用。 – Konamiman 2011-03-16 10:01:57

+0

在你的例子中,你试图传入一个零值,它是否与一个非零值一起工作? – pablo 2011-03-16 10:46:24

+0

尝试了值1,也没有工作。 – Konamiman 2011-03-16 10:48:02

0

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

+0

但该列实际上不可为空。无论如何,我尝试过,并没有工作。 – Konamiman 2011-03-16 10:01:21

+1

@Konamiman:当您将列设置为可空时,问题仍然存在......这意味着问题在其他地方。它可能是另一列......? – 2011-03-16 10:07:44

1

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

  1. 连接到数据库
  2. 使用dbms_session.set_sql_trace(真),以使一个SQL跟踪
  3. 从数据库做你的应用程序操作
  4. 断开
  5. 发现 - 或询问您的DBA - 以向您发送原始跟踪文件

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

这可能是一个触发器被解雇....