插入期间违反唯一约束:为什么? (甲骨文)
我正在尝试在表中创建一个新行。表上有两个约束——一个是关键字段 (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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
据推测,由于您没有为
DB_ID
列提供值,因此该值将由表中定义的行级 before insert 触发器填充。该触发器大概是从序列中选择值。由于数据是从生产数据库中移动的(大概是最近),我敢打赌,当复制数据时,序列也不会被修改。我猜测该序列生成的值远低于表中当前导致错误的最大
DB_ID
。您可以通过查看触发器来确定正在使用哪个序列并执行 a
并将其与
如果,正如我怀疑的那样,该序列正在生成数据库中已存在的值来确认此怀疑,您可以增加该序列,直到它是生成未使用的值,或者您可以更改它以将
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
and comparing that to
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 theINCREMENT
back to 1.您的错误看起来像是您正在复制数据库中已存在的主键。您应该修改您的 sql 代码,通过使用类似 IDENTITY 关键字的内容来实现它自己的主键。
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.
您似乎没有为主键字段 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)