Rails:违反 Oracle 约束
我正在对我继承的 Rails 站点进行维护工作;它由 Oracle 数据库驱动,我可以访问该站点的开发和生产安装(每个都有自己的 Oracle DB)。当尝试在生产站点而非开发站点上插入数据时,我遇到了 Oracle 错误:
ActiveRecord::StatementInvalid (OCIError: ORA-00001: unique constraint (DATABASE_NAME.PK_REGISTRATION_OWNERSHIP) violated: INSERT INTO registration_ownerships (updated_at, company_ownership_id, created_by, updated_by, registration_id, created_at) VALUES ('2006-05-04 16:30:47', 3, NULL, NULL, 2920, '2006-05-04 16:30:47')):
/usr/local/lib/ruby/gems/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:221:in `execute'
app/controllers/vendors_controller.rb:94:in `create'
据我所知(我使用 Navicat 作为 Oracle 客户端),开发站点的数据库架构是与实时站点相同。我不是 Oracle 专家;任何人都可以阐明为什么我会在一个安装中出现错误,而在另一个安装中不会出现错误?
顺便说一句,开发和生产的registration_ownerships表都填充了大量数据,包括country_ownership_id的重复条目(由索引PK_REGISTRATION_OWNERSHIP驱动)。如果您需要更多信息来排除故障,请告诉我。很抱歉我还没有提供更多信息,但我不确定哪些细节会有帮助。
更新:我尝试删除生产服务器上的约束,但没有效果;我也不想放弃该指数,因为我不确定可能会产生什么后果,而且我不想让生产变得比现在更不稳定。
奇怪的是,我尝试手动执行引发错误的 SQL,并且 Oracle 接受了插入语句(尽管我必须使用字符串文字将日期包装在 to_date() 调用中,以避开“ORA-01861:文字不匹配”格式字符串”错误)。这里可能发生了什么?
I'm doing maintenance work on a Rails site that I inherited; it's driven by an Oracle database, and I've got access to both development and production installations of the site (each with its own Oracle DB). I'm running into an Oracle error when trying to insert data on the production site, but not the dev site:
ActiveRecord::StatementInvalid (OCIError: ORA-00001: unique constraint (DATABASE_NAME.PK_REGISTRATION_OWNERSHIP) violated: INSERT INTO registration_ownerships (updated_at, company_ownership_id, created_by, updated_by, registration_id, created_at) VALUES ('2006-05-04 16:30:47', 3, NULL, NULL, 2920, '2006-05-04 16:30:47')):
/usr/local/lib/ruby/gems/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:221:in `execute'
app/controllers/vendors_controller.rb:94:in `create'
As far as I can tell (I'm using Navicat as an Oracle client), the DB schema for the dev site is identical to that of the live site. I'm not an Oracle expert; can anyone shed light on why I'd be getting the error in one installation and not the other?
Incidentally, both dev and production registration_ownerships tables are populated with lots of data, including duplicate entries for country_ownership_id (driven by index PK_REGISTRATION_OWNERSHIP). Please let me know if you need more information to troubleshoot. I'm sorry I haven't given more already, but I just wasn't sure which details would be helpful.
UPDATE: I've tried dropping the constraint on the production server but it had no effect; I didn't want to drop the index as well because I'm not sure what the consequences might be and I don't want to make production less stable than it already is.
Curiously, I tried executing by hand the SQL that was throwing an error, and Oracle accepted the insert statement (though I had to wrap the dates in to_date() calls with string literals to get around an "ORA-01861: literal does not match format string" error). What might be going on here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
根据约束的名称
PK_REGISTRATION_OWNERSHIP
,您存在主键违规。如果这些数据库没有同步维护此数据,则某些人/某人已经将一条记录插入到生产数据库的registration_ownerships
表中,其中company_ownership_id
=2 ®istration_id
=2920。 (我根据名称猜测具体情况)如果这组特定的值需要存在于生产数据库中,
1)检查已存在的内容是否不是您要插入的内容。如果是的话,你就完成了。
2) 如果您需要按原样插入示例数据,则需要修改现有数据&重新插入它(以及所有依赖/引用记录),然后您可以插入您的值。
Based on the name of the constraint,
PK_REGISTRATION_OWNERSHIP
, you have a primary key violation. If these databases aren't maintaining this data in lockstep, something/someone has already inserted a record into theregistration_ownerships
table in your production database withcompany_ownership_id
=2 ®istration_id
=2920. (I'm guessing at the specifics based on the names)If this particular set of values needs to exist in the production database,
1) check that what's already there isn't what you're trying to insert. if it is, you're done.
2) If you need to insert your sample data as-is, you need to modify the existing data & re-insert it (and all the dependent/refering records), then you can insert your values.
如果查询表并没有找到匹配的行,则可能是以下原因之一:
另外,检查 dev 和 prod 之间唯一约束的状态是否相同。也许 dev 上的索引被标记为未验证 - 检查该索引是否存在于 dev 上并且是一个唯一索引(注意:在 Oracle 中,可能有一个由非唯一索引验证的唯一约束)。
If you query the table and find no matching rows, then one of the following may be the cause:
Also, check that the state of the unique constraint is the same between dev and prod. Perhaps the one on dev is marked as not validated - check that the index exists on dev and is a unique index (note: in Oracle it is possible to have a unique constraint validated by a non-unique index).
仔细查看约束的基础唯一索引。删除约束不会改变任何内容的原因是因为索引仍然存在,并且它是唯一索引。以下内容告诉您有关两种环境中索引的什么信息?两个索引都有效吗?两者定义相同吗?它们真的都是独一无二的吗?
Take a hard look at the underlying unique index for the constraint. The reason dropping the constraint doesn't change anything is because the index remains, and it's a unique index. What does the following tell you about the indexes in both environments? Are both indexes valid? Are both defined the same? Are they both actually unique?
碰巧的是,目录中有一份“注册”模型的备用副本;即使它有不同的名称(“registrations_2349871.rb”或类似的名称)Rails 运行所有模型功能(保存、验证等)两次,因此违反了关键约束!我以前从未见过这样的行为。删除恶意文件解决了问题。
As it happens, there was a spare copy of the "registrations" model lying around the directory; even though it had a different name ("registrations_2349871.rb" or something like that) Rails was running all model functionality (saving, validating, etc) twice, hence the key constraint violation! I've never seen behavior like this before. Deleting the rogue file solved the problem.