【问题标题】:Unique constraint violation during insert: why? (Oracle)插入期间违反唯一约束:为什么? (甲骨文)
【发布时间】:2011-11-26 03:22:37
【问题描述】:

我正在尝试在表中创建一个新行。表上有两个约束——一个是键字段(DB_ID),另一个约束一个值是几个字段 ENV 之一。当我进行插入时,我没有将关键字段作为我尝试插入的字段之一包含在内,但我收到了这个错误:

unique constraint (N390.PK_DB_ID) violated

这是导致错误的 SQL:

insert into cmdb_db 
   (narrative_name, db_name, db_type, schema, node, env, server_id, state, path) 
values 
   ('Test Database', 'DB', 'TYPE', 'SCH', '', 'SB01', 381, 'TEST', '')

我唯一能发现的是,如果手动插入行,Oracle 可能会尝试分配一个已经在使用的 DB_ID。该数据库中的数据以某种方式从生产数据库中恢复/移动,但我不知道具体是如何完成的。

有什么想法吗?

【问题讨论】:

    标签: oracle unique-constraint


    【解决方案1】:

    您似乎没有为主键字段 DB_ID 提供值。如果这是主键,则必须为该列提供唯一值。不提供它的唯一方法是创建一个数据库触发器,该触发器在插入时将提供一个值,该值很可能源自一个序列。

    如果这是从另一个数据库恢复,并且在这个新实例上有一个序列,它可能会尝试重用一个值。如果旧数据具有从 1 到 1000 的唯一键并且您当前的序列为 500,那么它将生成已经存在的值。如果此表确实存在序列并且它正在尝试使用它,则需要将表中的值与序列的当前值进行协调。

    可以使用 SEQUENCE_NAME.CURRVAL 来查看序列的当前值(当然如果存在的话)

    【讨论】:

    • 我在数据库上的信息表明,插入新行时应该自动生成密钥——这就是我不提供 DB_ID 值的原因。此外,同样的技术适用于数据库中其他类似的表——它们具有自动生成的 ID 键。
    • 您是否能够查询数据字典以查看新环境中是否存在必要的触发器/序列?也许并非所有东西都来自旧环境。
    【解决方案2】:

    您的错误看起来像是在复制数据库中已经存在的主键。你应该修改你的 sql 代码,通过使用 IDENTITY 关键字来实现它自己的主键。

    CREATE TABLE [DB] (
        [DBId] bigint NOT NULL IDENTITY,
        ...
    
        CONSTRAINT [DB_PK] PRIMARY KEY ([DB] ASC),
    
    ); 
    

    【讨论】:

    • IDENTITY 不是 Oracle 中的有效关键字。
    • 这对 Oracle 来说是无效的声明
    • 您说得对。我的解决方案适用于 SQL,而不适用于 Oracle。如果你想在 Oracle 中复制 SQL 的身份,你会想使用序列link@Justin_Cave 在他的回答中有一个很好的实现。
    【解决方案3】:

    大概,由于您没有为DB_ID 列提供值,因此该值由表上定义的插入触发器之前的行级填充。据推测,该触发器正在从序列中选择值。

    由于数据是从生产数据库中移动的(可能是最近),我敢打赌,当数据被复制时,序列也没有被修改。我猜想该序列生成的值远低于当前表中导致错误的最大 DB_ID

    您可以通过查看触发器以确定正在使用的序列并执行此操作来确认此怀疑

    SELECT <<sequence name>>.nextval
      FROM dual
    

    并将其与

    进行比较
    SELECT MAX(db_id)
      FROM cmdb_db
    

    如果我怀疑该序列正在生成数据库中已经存在的值,您可以递增该序列直到它生成未使用的值,或者您可以更改它以将 INCREMENT 设置为非常大的值,获取nextval 一次,然后将INCREMENT 设置回 1。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-01
      • 2021-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多