3

我正在使用 Oracle 数据库。我们在调用我们的服务时经常看到失败。当我查看日志时,我在表上看到以下异常

java.sql.BatchUpdateException:ORA-00001:违反了唯一约束 (DBSCHEMA.IDX_CO_DETAILS)。

我检查了表上的索引以获取索引名称 DBSCHEMA.IDX_CO_DETAILS 。

它不包括任何列(INCLUDE_COLUMN 为空)。我怎么知道这个约束是为了什么?是主键约束吗?

我们将休眠用于 ORM。下面是休眠上下文中的回溯

Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
4

1 回答 1

12

唯一约束强制执行唯一性。与主键约束不同,它将允许空值。

您的错误意味着当数据库已配置为明确禁止时,您正在插入重复数据。

您可以通过对all_constraints运行以下查询来找出表上有哪些约束。链接解码列CONSTRAINT_TYPE,例如P是主键和U唯一键。

select *
  from all_constraints uc
 where uc.table_name = 'MY_TABLE'
   and owner = 'DBSCHEMA'

要找出约束中的列,all_cons_columns请改用,或将两者组合到一个查询中:

select uc.*, ucc.column_name, ucc.position
  from all_constraints uc
  join all_cons_columns ucc
    on uc.owner = ucc.owner
   and uc.table_name = ucc.table_name
   and uc.constraint_name = ucc.constraint_name
 where uc.table_name = 'MY_TABLE'
   and uc.owner = 'DBSCHEMA'

对于任一查询,您都可以添加附加条件and constraint_name = 'IDX_CO_DETAILS'以找出似乎导致您的问题的特定约束的详细信息。


出于几个原因,您的评论有点令人惊讶。即使是系统创建的约束,例如在创建表时没有指定名称的情况下在线定义的约束,也应该显示出来。此外,约束名称IDX...暗示它是一个索引。

如果您运行以下查询,它应该会告诉您该对象是否存在于数据库中:

select *
  from all_objects
 where object_name = 'IDX_CO_DETAILS'

我希望OBJECT_TYPE这个查询返回的是'INDEX'.

此后,以下查询将返回具有该名称的每个索引、索引的类型、与之关联的表以及该表的所有者。

select *
  from all_indexes
 where index_name = 'IDX_CO_DETAILS'

根据您的错误判断,我进一步希望UNIQUNESS此查询返回的列是'UNIQUE'.

这应该可以帮助您追踪对象。

也可以使用系统包dbms_metadata来追踪对象的DDL;小心它返回一个clob。

select dbms_metadata.get_ddl('INDEX','IDX_CO_DETAILS', schema => 'DBSCHEMA') 
  from dual

该参数schema是可选的。

于 2012-06-10T15:07:23.890 回答