Oracle中违反了完整性约束

时间:2012-12-11 11:19:31

标签: sql oracle oracle11g

我有两个Oracle表:

CREATE TABLE MANAGEDSYSTEMS(
  MSYSTEMID INTEGER NOT NULL,
  MSYSTEMGROUPID INTEGER,
  SPECIALNUMBER VARCHAR2(40 ),
  SERIALNUMBER VARCHAR2(30 ),
  MSYSTEMSTATUS VARCHAR2(30 ),
  MSYSTEMNAME VARCHAR2(60 ),
  IPADDRESS VARCHAR2(30 ),
  DATEMSYSTEMADDED TIMESTAMP(6),
  DESCRIPTION CLOB
)
/

-- ADD KEYS FOR TABLE MANAGEDSYSTEMS

ALTER TABLE MANAGEDSYSTEMS ADD CONSTRAINT MSKEY PRIMARY KEY (MSYSTEMID)
/


CREATE TABLE AGENTS(
  AGENTID INTEGER NOT NULL,
  MSYSTEMID INTEGER,
  AGENTGROUPID INTEGER,
  AGENTSERIALNUMBER VARCHAR2(60 ),
  AGENTSTATUS VARCHAR2(30 ),
  AGENTOS VARCHAR2(60 ),
  AGENTIPADDRESS VARCHAR2(40 ),
  LASTSYNC TIMESTAMP(6),
  DATEAGENTADDED TIMESTAMP(6),
  CPULOADLIMIT INTEGER,
  RAMLOADLIMIT INTEGER,
  HDDSPACELIMIT INTEGER,
  NETWORKUPLIMIT INTEGER,
  NETWORKDOWNLIMIT INTEGER,
  REPORTUSERLOGINS VARCHAR2(30 ),
  CANEXECCOMMANDS VARCHAR2(30 ),
  SYNCHRONIZATIONTIME VARCHAR2(30 ),
  DATALIMITSPEAKTIMES INTEGER,
  DESCRIPTION CLOB
)
/

-- ADD KEYS FOR TABLE AGENTS

    ALTER TABLE AGENTS ADD CONSTRAINT AGENTID PRIMARY KEY (AGENTID)
ALTER TABLE AGENTS ADD CONSTRAINT MSYSTEMID FOREIGN KEY (MSYSTEMID) REFERENCES MANAGEDSYSTEMS (MSYSTEMID)

我想将'Agent'分配到'Managedsystems'表中。如您所见,我有一个表外键 - 用户必须首先创建受管系统,然后创建代理。但我还想给出一个选项来创建代理而无需分配托管系统。当我尝试将托管系统ID的密钥更改为代理程序表时,我收到此错误:

Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-02291: integrity constraint (ADMIN.MSYSTEMID) violated - parent key not found

似乎我无法分配空值。我该如何解决这个问题?

更新:

我使用此SQL语句更新代理表:

String sql = "UPDATE AGENTS "
                             + " SET AGENTID = ?, MSYSTEMID = ?, AGENTGROUPID = ?, AGENTSERIALNUMBER = ?, AGENTSTATUS = ?, AGENTOS = ?, AGENTIPADDRESS = ?, "
                             + " LASTSYNC = to_timestamp(?, " + ts_template + "), DATEAGENTADDED = to_timestamp(?, " + ts_template + "), "
                             + " CPULOADLIMIT = ?, RAMLOADLIMIT = ?, HDDSPACELIMIT = ?, NETWORKUPLIMIT = ?, NETWORKDOWNLIMIT = ?, REPORTUSERLOGINS = ?, "
                             + " CANEXECCOMMANDS = ?, SYNCHRONIZATIONTIME = ?, DATALIMITSPEAKTIMES = ?, "
                             + " DESCRIPTION = ? WHERE AGENTID = ?";

2 个答案:

答案 0 :(得分:1)

您在更新语句中绑定了什么值?如果您不想分配,AGENTS.MSYSTEMID的值应该是父表(MANAGEDSYSTEMS)或null中存在的任何值。所以代码应该是这样的:

String sql = "...";
..
PreparedStatement ps = ...
ps.setInt(1, ...);
if (you want to assign AGENTS.MSYSTEMID) {
    ps.setInt(2, ...);
} else {
    ps.setNull(2, ...);
}
...

答案 1 :(得分:0)

如果您在同一个事务中插入两个表,但是您想先插入子表,那么最初会使您的FK延期。

SQL> CREATE TABLE MANAGEDSYSTEMS(
  2    MSYSTEMID INTEGER NOT NULL,
  3    MSYSTEMGROUPID INTEGER,
  4    SPECIALNUMBER VARCHAR2(40 ),
  5    SERIALNUMBER VARCHAR2(30 ),
  6    MSYSTEMSTATUS VARCHAR2(30 ),
  7    MSYSTEMNAME VARCHAR2(60 ),
  8    IPADDRESS VARCHAR2(30 ),
  9    DATEMSYSTEMADDED TIMESTAMP(6),
 10    DESCRIPTION CLOB
 11  )
 12  /

Table created.

SQL> ALTER TABLE MANAGEDSYSTEMS ADD CONSTRAINT MSKEY PRIMARY KEY (MSYSTEMID);

Table altered.

SQL> CREATE TABLE AGENTS(
  2    AGENTID INTEGER NOT NULL,
  3    MSYSTEMID INTEGER,
  4    AGENTGROUPID INTEGER,
  5    AGENTSERIALNUMBER VARCHAR2(60 ),
  6    AGENTSTATUS VARCHAR2(30 ),
  7    AGENTOS VARCHAR2(60 ),
  8    AGENTIPADDRESS VARCHAR2(40 ),
  9    LASTSYNC TIMESTAMP(6),
 10    DATEAGENTADDED TIMESTAMP(6),
 11    CPULOADLIMIT INTEGER,
 12    RAMLOADLIMIT INTEGER,
 13    HDDSPACELIMIT INTEGER,
 14    NETWORKUPLIMIT INTEGER,
 15    NETWORKDOWNLIMIT INTEGER,
 16    REPORTUSERLOGINS VARCHAR2(30 ),
 17    CANEXECCOMMANDS VARCHAR2(30 ),
 18    SYNCHRONIZATIONTIME VARCHAR2(30 ),
 19    DATALIMITSPEAKTIMES INTEGER,
 20    DESCRIPTION CLOB
 21  )
 22  /

Table created.

SQL> ALTER TABLE AGENTS ADD CONSTRAINT AGENTID PRIMARY KEY (AGENTID);

Table altered.

SQL> ALTER TABLE AGENTS ADD CONSTRAINT MSYSTEMID FOREIGN KEY (MSYSTEMID) REFERENCES MANAGEDSYSTEMS (MSYSTEMID) initially deferred;

Table altered.

SQL> insert into AGENTS (AGENTID, MSYSTEMID, AGENTGROUPID, AGENTSERIALNUMBER) values (1, 1, 1, 'x');

1 row created.

SQL> insert into MANAGEDSYSTEMS (MSYSTEMID, MSYSTEMGROUPID, SPECIALNUMBER) values (1, 1, 'x');

1 row created.

SQL> commit;

Commit complete.

它不会让你在没有父母的情况下完成交易:

SQL> insert into AGENTS (AGENTID, MSYSTEMID, AGENTGROUPID, AGENTSERIALNUMBER) values (2, 2, 1, 'x');

1 row created.

SQL> commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02291: integrity constraint (DTD_TRADE.MSYSTEMID) violated - parent key not
found