简体   繁体   English

尝试插入schema.table.ID时出现ORA-01400

[英]ORA-01400 when trying to insert into schema.table.ID

I have a table that stores rejected contract proposals. 我有一张桌子,存储被拒绝的合同建议。

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)
;

(Script generated by Visual Studio 2010) (脚本由Visual Studio 2010生成)

This table has a simple Trigger, where the value of STC_ID is set: 该表具有一个简单的触发器,其中设置了STC_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 is a simple sequence. SEQ_STATUS_ID是一个简单的序列。

Here's my problem: 这是我的问题:

I can successfuly execute this insert in the VS2010 query window: 我可以在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'
);

But, when I try to insert using EF, I'm getting this exception: 但是,当我尝试使用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

I'm using this code to insert 我正在使用此代码插入

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();

I'm using VS2010, Oracle 11g (CentOS Server), ODP.NET client 11.2.0.3.0 Production, .NET Framework 4.0, EF 4. 我正在使用VS2010,Oracle 11g(CentOS服务器),ODP.NET客户端11.2.0.3.0生产,.NET Framework 4.0,EF 4。

Check this: http://www.oracle.com/technetwork/issue-archive/2011/11-sep/o51odt-453447.html 检查以下内容: http : //www.oracle.com/technetwork/issue-archive/2011/11-sep/o51odt-453447.html

Particularly, section "Triggers and Sequences" 特别是,“触发器和序列”部分

From the Tools menu, select Run SQL Plus Script. 从“工具”菜单中,选择“运行SQL Plus脚本”。 Browse to the location where you extracted the code and scripts, select the triggers.sql script, select the HR connection from the list, and click Run. 浏览到提取代码和脚本的位置,选择triggers.sql脚本,从列表中选择HR连接,然后单击“运行”。 The INSERTEMPLOYEES trigger created by the script generates a new sequence for EMPLOYEE_ID whenever NULL is passed in for that value........ 每当为该值传递NULL时,脚本创建的INSERTEMPLOYEES触发器都会为EMPLOYEE_ID生成新序列。

Your code works, except for a problem with 您的代码可以正常工作,但以下问题除外

ent.UNV_STATUS_CONTRATO.AddObject(statusContrato);

Is UNV_STATUS_CONTRATO another table? UNV_STATUS_CONTRATO是另一个表吗? Why is it not 为什么不是

ent.STATUS_CONTRATO.AddObject(statusContrato);

That should work just fine. 那应该很好。

However, you might find it preferable to get the sequence value from your code and apply it to your ID column in memory before saving changes. 但是,您可能会更希望从代码中获取序列值并将其应用于内存中的ID列,然后再保存更改。 So something like this: 所以像这样:

    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();
        }
    }

Then you call that method before SaveChanges() . 然后,在SaveChanges()之前调用该方法。

Personally, I prefer to handle it this way so that my in-memory entity then also has the correct ID, instead of just having a 0, or having to query it right back out, etc. 就我个人而言,我更喜欢这样处理,以便我的内存中实体也具有正确的ID,而不是只有0或必须直接查询回来,等等。

Also, the method described here under Triggers and Sequences can supposedly wire up an entity's PK to a sequence. 同样, 这里在“触发器和序列”下描述的方法可以将实体的PK连接到序列。

You need to specify in your EF Mapping that the DB does not generate the key for you and EF should use the Key you provided... 您需要在EF映射中指定数据库不会为您生成密钥,并且EF应该使用您提供的密钥...

see my post in the following thread: https://stackoverflow.com/a/18635325/1712367 请在以下线程中查看我的帖子: https : //stackoverflow.com/a/18635325/1712367

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM