插入期间违反唯一约束:为什么? (甲骨文)

发布于 2024-12-06 15:35:04 字数 525 浏览 0 评论 0原文

我正在尝试在表中创建一个新行。表上有两个约束——一个是关键字段 (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。该数据库中的数据以某种方式从生产数据库中恢复/移动,但我不知道如何完成此操作的详细信息。

有什么想法吗?

I'm trying to create a new row in a table. There are two constraints on the table -- one is on the key field (DB_ID), the other constrains a value to be one of several the the field ENV. When I do an insert, I do not include the key field as one of the fields I'm trying to insert, yet I'm getting this error:

unique constraint (N390.PK_DB_ID) violated

Here's the SQL that causes the error:

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', '')

The only thing I've been able to turn up is the possibility that Oracle might be trying to assign an already in-use DB_ID if rows were inserted manually. The data in this database was somehow restored/moved from a production database, but I don't have the details as to how that was done.

Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萌面超妹 2024-12-13 15:35:04

据推测,由于您没有为 DB_ID 列提供值,因此该值将由表中定义的行级 before insert 触发器填充。该触发器大概是从序列中选择值。

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

您可以通过查看触发器来确定正在使用哪个序列并执行 a

SELECT <<sequence name>>.nextval
  FROM dual

并将其与

SELECT MAX(db_id)
  FROM cmdb_db

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

Presumably, since you're not providing a value for the DB_ID column, that value is being populated by a row-level before insert trigger defined on the table. That trigger, presumably, is selecting the value from a sequence.

Since the data was moved (presumably recently) from the production database, my wager would be that when the data was copied, the sequence was not modified as well. I would guess that the sequence is generating values that are much lower than the largest DB_ID that is currently in the table leading to the error.

You could confirm this suspicion by looking at the trigger to determine which sequence is being used and doing a

SELECT <<sequence name>>.nextval
  FROM dual

and comparing that to

SELECT MAX(db_id)
  FROM cmdb_db

If, as I suspect, the sequence is generating values that already exist in the database, you could increment the sequence until it was generating unused values or you could alter it to set the INCREMENT to something very large, get the nextval once, and set the INCREMENT back to 1.

唱一曲作罢 2024-12-13 15:35:04

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

CREATE TABLE [DB] (
    [DBId] bigint NOT NULL IDENTITY,
    ...

    CONSTRAINT [DB_PK] PRIMARY KEY ([DB] ASC),

); 

Your error looks like you are duplicating an already existing Primary Key in your DB. You should modify your sql code to implement its own primary key by using something like the IDENTITY keyword.

CREATE TABLE [DB] (
    [DBId] bigint NOT NULL IDENTITY,
    ...

    CONSTRAINT [DB_PK] PRIMARY KEY ([DB] ASC),

); 
脱离于你 2024-12-13 15:35:04

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

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

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

It looks like you are not providing a value for the primary key field DB_ID. If that is a primary key, you must provide a unique value for that column. The only way not to provide it would be to create a database trigger that, on insert, would provide a value, most likely derived from a sequence.

If this is a restoration from another database and there is a sequence on this new instance, it might be trying to reuse a value. If the old data had unique keys from 1 - 1000 and your current sequence is at 500, it would be generating values that already exist. If a sequence does exist for this table and it is trying to use it, you would need to reconcile the values in your table with the current value of the sequence.

You can use SEQUENCE_NAME.CURRVAL to see the current value of the sequence (if it exists of course)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文