Oracle &引用;ORA-00001:违反了唯一约束(约束“名称”);错误,即使我没有检查

Oracle &引用;ORA-00001:违反了唯一约束(约束“名称”);错误,即使我没有检查,oracle,sql-insert,Oracle,Sql Insert,我试图通过应用程序在表中插入一些值,并得到问题“ORA-00001:违反了唯一约束(约束名称)”。我有下表: CREATE TABLE EMPLOYEE ( EMP_ID VARCHAR2(32) NOT NULL, NAME VARCHAR2(30) NOT NULL, TIME TIMESTAMP(3), PRIMARY KEY(EMP_ID) ); 我在过程中有以下语句,即使在插入之前我没有检查是否存在,该INSERT语句仍然失败: INSERT INTO EMPLOYEE (EMP_I

我试图通过应用程序在表中插入一些值,并得到问题“ORA-00001:违反了唯一约束(约束名称)”。我有下表:

CREATE TABLE EMPLOYEE
(
EMP_ID VARCHAR2(32) NOT NULL,
NAME VARCHAR2(30) NOT NULL,
TIME TIMESTAMP(3),
PRIMARY KEY(EMP_ID)
);
我在过程中有以下语句,即使在插入之前我没有检查是否存在,该INSERT语句仍然失败:

INSERT INTO EMPLOYEE
(EMP_ID, NAME, TIME)
( SELECT v_empid ,
sys_context('USERENV','SID'),
SYSTIMESTAMP+INTERVAL '10' SECOND 
FROM DUAL
WHERE NOT EXISTS ( SELECT 1
FROM EMPLOYEE
WHERE EMP_ID = v_empid) );
上面的过程几乎是同时从多个服务调用的,并行事务是否有问题,比如多个会话试图插入到同一个表中?
在此感谢您提供的任何帮助。

对我来说,似乎有两个会话试图同时插入同一用户

下面是我如何复制它的:

第一步。会议A:

INSERT INTO test_EMPLOYEE(EMP_ID, NAME, TIME)
(SELECT 123, sys_context('USERENV','SID'), SYSTIMESTAMP+INTERVAL '10' SECOND 
   FROM DUAL
  WHERE NOT EXISTS ( SELECT 1 FROM test_EMPLOYEE WHERE EMP_ID = 123));
commit;
第二步。会议B:

-- same query as Session A
INSERT INTO test_EMPLOYEE(EMP_ID, NAME, TIME)
(SELECT 123, sys_context('USERENV','SID'), SYSTIMESTAMP+INTERVAL '10' SECOND 
   FROM DUAL
  WHERE NOT EXISTS ( SELECT 1 FROM test_EMPLOYEE WHERE EMP_ID = 123));
第三步。会议A:

INSERT INTO test_EMPLOYEE(EMP_ID, NAME, TIME)
(SELECT 123, sys_context('USERENV','SID'), SYSTIMESTAMP+INTERVAL '10' SECOND 
   FROM DUAL
  WHERE NOT EXISTS ( SELECT 1 FROM test_EMPLOYEE WHERE EMP_ID = 123));
commit;
瞧:会话B因违反约束而失败


所以我认为是用户或数据库之外的东西导致了错误

它总是会出现错误,还是(有时)只会同时运行?如果你总是得到它-至少对于一个特定的ID-被报告的约束实际上是你的PK,或者你可能在表上有一个触发器插入到其他地方,这是错误的吗?这并不总是正确的。仅当多个会话试图运行该过程,并且我在INSERT语句之后有COMMIT时。由于过程中只有一个insert语句,并且我们得到的约束也与EMP_ID的主键相关,因此在同一语句中失败。如果我们尝试从多个会话中插入相同的键,并且尝试从两个会话中插入相同的键,则这是正确的。但我在过程中的INSERT语句之后进行了COMMIT,并且从应用程序端调用了过程,它应该等待另一个会话释放锁或其他什么?我主要关心的是我们通常如何在事务系统中处理此类事务?@NaveenReddyCH在会话A已插入和提交表之间获得DML锁。所以,没有其他人可以操纵它。但它并不影响select语句。同时,会话B执行了所有选择,并确保没有其他同名用户,只需等待锁被释放即可插入数据,而无需进行任何额外检查。我将从查询中删除“notexists”部分,并在代码中处理(或忽略)异常。