3

Oracleデータベースを使用しています。私たちのサービスへの呼び出しで頻繁に失敗が見られます。ログを見ると、テーブルに次の例外があります。

java.sql.BatchUpdateException:ORA-00001:一意性制約(DBSCHEMA.IDX_CO_DETAILS)に違反しました。

テーブルのインデックスでインデックス名DBSCHEMA.IDX_CO_DETAILSを確認しました。

列は含まれていません(INCLUDE_COLUMNはnullです)。この制約が何であるかをどうやって知ることができますか?それは主キーの制約ですか?

ORMにはHibernateを使用しています。以下は、休止状態のコンテキストでのバックトレースです

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

一意性制約は、まあ、一意性を強制します。主キー制約とは異なり、nullを許可します。

エラーは、データベースが明示的に禁止するように構成されている場合に、重複データを挿入していることを意味します。

all_constraintsで次のクエリを実行すると、テーブルにどのような制約があるかを確認できます。リンクは列をデコードしますCONSTRAINT_TYPE。たとえばP、主キーとU一意キーです。

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

all_cons_columns代わりに、制約内の列を確認するには、または2つを1つのクエリに結合します。

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 に答える