2011-03-16 183 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(純文本文件)中找到您的代碼並查看發生錯誤時會發生什麼。

這可能是一個觸發器被解僱....