ORA 000001违反了唯一约束



我有一个表的Insert语句,该表的主键为dep_id和emp_id。我的java程序为一个新记录生成一个新的emp_id并插入它。例如,如果我的dep_id=100和emp_id=25,我不能插入dep_id=100和emp_id=26的记录,但我可以插入dep_id=100和emp_id=27的记录。我通过select语句检查了这种组合(dep_id=100和emp_id=26)是否存在。没有那种事。我还是做了DELETE from where dep_id=100 and emp_id=26 and Commit只是为了确定,然后尝试插入,但仍然不起作用。可能出了什么问题?以下是代码:修改的DDL和Insert语句(从Eclipse控制台获得)

                                                                                    CREATE  TABLE "TestDB"."table1" 
 (  "dep_id" NUMBER(20,0), 
"emp_id" NUMBER(20,0), 
"STATUS" VARCHAR2(10 BYTE), 
"PRO_LEVEL" VARCHAR2(14 BYTE), 
"new_sql_stmt" VARCHAR2(4000 BYTE), 
"DEL_TEM" VARCHAR2(500 BYTE), 
"tab_name" VARCHAR2(4000 BYTE), 
"COL_NAME" VARCHAR2(4000 BYTE), 
"QUERY_TYPE" VARCHAR2(4000 BYTE), 
"NAME" VARCHAR2(4000 BYTE), 
"DT_MODIFIED" DATE DEFAULT SYSDATE

)

  CREATE UNIQUE INDEX "TestDB"."table1_PK" ON "TestDB"."table1" ("dep_id", "emp_id") 

     INSERT into table1            (dep_id,emp_id,status,new_sql_stmt,tab_name,col_name,query_type,NAME)values('100','26','Unlock','INSERT into testTab(id_some,nm_some,id_some_origin,flag,some_code,author,order) values  (''S11111111'',''trialSome00'','''',''y'','''',''100'',0)','testTab','nm_some','INSERT','trialSome00')

请注意,Insert语句本身有另一个Insert语句作为值。这个Insert语句(主语句)在应用程序的许多其他地方都使用。此外,我使用的dep_id 100是一个测试dep_id。除了我没有人使用它。

创建Oracle序列:

CREATE SEQUENCE emp_id_seq MINVALUE 1 START WITH 1 INCREMENT BY 1; 

现在,您可以从代码中调用该序列上的"nextval"方法(这可以用JDBC或几乎所有ORM(如果不是全部的话)来完成),也可以在该列上放置一个触发器,该触发器在执行插入操作时自动从序列中获取nextval并将其插入表中(oracle上的IIRC会在触发器中使用"BEFOREISERT"运算符)。

例如

create or replace trigger mytable_emp_id_trigger
before insert on mytable
for each row
begin
    select emp_id_seq.nextval into :emp.id from dual;
end;
/

这样做是线程安全的,您永远不应该看到这样的冲突发生。

如果您坚持在java代码中执行此操作(比如DBA不允许您创建另一个序列,但为什么不呢?如果他们不这样做,我会感到惊讶),那么您必须确保该方法的线程安全。最好使用同步方法创建一个singleton(您可以创建singleton EJB),以提供下一个值。您可以从该singleton类获得id,而不是从任何其他类或ejb获得id,以避免出现像现在这样的问题(无论当前问题是否是因为这个原因,您现在遇到的是多线程与多线程环境中的非同步方法发生冲突的典型情况)。

同时,如果您真的想了解发生了什么,请使用调试器并观察变量,以查看现有代码正在生成什么。调试器和手表是你的朋友。你最好的朋友。

最新更新