2012-08-15 40 views
4

我有一個表存儲被拒絕的合同建議。ORA-01400當試圖插入到schema.table.ID

TRIGGER "STATUS_CONTRATO_TRIGGER1" 
    BEFORE 
    INSERT 
    ON "STATUS_CONTRATO" 
    FOR EACH ROW 

when (new.STC_ID = 0) 
DECLARE 
BEGIN 
    SELECT SEQ_STATUS_ID.NEXTVAL INTO :NEW.STC_ID FROM DUAL; 
END; 

SEQ_STATUS_ID是一個簡單的序列:

CREATE TABLE "STATUS_CONTRATO" (
    "STC_ID" NUMBER NOT NULL, 
    "CTB_CONTRATO" NUMBER NOT NULL, 
    "STC_DATA" DATE NOT NULL, 
    "STC_OBSERVACAO" VARCHAR2(200) NOT NULL, 
    CONSTRAINT "STATUS_CONTRATO_PK" 
    PRIMARY KEY ("STC_ID") 
    ENABLE 
    VALIDATE, 
    CONSTRAINT "FK_CONTRATO" 
    FOREIGN KEY ("CTB_CONTRATO") 
     REFERENCES "CONTRATO" (CTB_CONTRATO) 
     ON DELETE SET NULL 
    ENABLE 
    VALIDATE) 
; 

這個表有一個簡單的觸發器,其中的STC_ID值被設置(由Visual Studio 2010生成的腳本)。

這裏是我的問題:

我successfuly在VS2010查詢窗口中執行此插入:

insert into myschema.STATUS_CONTRATO s(
    s.STC_ID, s.CTB_CONTRATO, s.STC_DATA, s.STC_OBSERVACAO 
)values(
    0, 10, SYSDATE, 'Inserting by hand works' 
); 

但是,當我嘗試插入使用EF,我得到這個異常:

System.Data.UpdateException: An error occurred while updating the entries. 
See the inner exception for details. ---> Oracle.DataAccess.Client.OracleException: 
ORA-01400: cannot insert NULL into ("MYSCHEMA"."STATUS_CONTRATO"."STC_ID") 
ORA-06512: at line 4 

我使用這個代碼中插入

STATUS_CONTRATO statusContrato = new STATUS_CONTRATO() { 
    STC_ID = 0, 
    CTB_CONTRATO = codContrato, 
    STC_DATA = DateTime.Today, 
    STC_OBSERVACAO = observacao 
}; 
ent.STATUS_CONTRATO.AddObject(statusContrato); 
ent.SaveChanges(); 

我使用VS2010,的Oracle 11g(CentOS的服務器),ODP.NET客戶11.2.0.3.0生產,.NET Framework 4.0中,EF 4

+0

嘗試使用System.Data.OracleClient並檢查問題是否仍然存在 – Nathan 2012-08-15 15:49:35

+0

@Nathan System.Data.OracleClient不是EF提供程序。 – hmqcnoesy 2012-08-15 16:04:33

+0

我已經從'System.Data.OracleClient'更改了,因爲它沒有正確綁定系統 – 2012-08-15 16:09:04

回答

3

檢查:http://www.oracle.com/technetwork/issue-archive/2011/11-sep/o51odt-453447.html

特別是,部分「觸發器和序列」

從工具菜單中,選擇運行SQL Plus腳本。瀏覽到您提取代碼和腳本的位置 ,選擇 triggers.sql腳本,從列表中選擇HR連接,然後單擊 運行。由腳本創建的INSERTEMPLOYEES觸發生成一個新的 序列NULL時傳入該值EMPLOYEE_ID ........

+1

的另一部分中的參數,這些參數的工作方式是將觸發器更改爲看起來像文章的zipfile中提供的觸發器,並對'STC_ID = 0'語句 – 2012-08-15 21:06:24

1

你的代碼工作,除了一個問題

ent.UNV_STATUS_CONTRATO.AddObject(statusContrato); 

UNV_STATUS_CONTRATO另一張桌子?爲什麼不是

ent.STATUS_CONTRATO.AddObject(statusContrato); 

這應該工作得很好。

但是,您可能會發現最好從代碼中獲取序列值,並在保存更改之前將其應用於內存中的ID列。所以像這樣:

public static int GetSequenceNextVal() 
    { 
     using (YourEntities entities = new YourEntities()) 
     { 
      var sql = "select myschema.SEQ_STATUS_ID.NEXTVAL from dual"; 
      var qry = entities.ExecuteStoreQuery<decimal>(sql); 
      return (int)qry.First(); 
     } 
    } 

然後你在SaveChanges()之前調用該方法。

就個人而言,我更喜歡這樣處理,使我在內存中的實體,然後也有正確的ID,而不是僅僅有一個0,或有查詢它的右後衛了,等

還的,觸發器和序列下的here所描述的方法可以將實體的PK連接到一個序列。

+0

'UNV_'只是我們用於表格的前綴。我在問題的其他部分省略了它,忘記了在這裏省略。 – 2012-08-15 19:23:02

+0

'StoreGeneratedPattern =「Identity」'已經在.edmx文件中設置。 – 2012-08-15 19:40:55

相關問題