Rails:Oracle约束违规

时间:2010-04-12 19:24:30

标签: ruby-on-rails oracle constraints ora-00001

我正在继承我继承的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专家;任何人都可以解释为什么我会在一次安装而不是另一次安装中得到错误?

顺便说一句,dev和production registration_ownerships表都填充了大量数据,包括country_ownership_id的重复条目(由索引PK_REGISTRATION_OWNERSHIP驱动)。如果您需要更多信息进行故障排除,请与我们联系。对不起,我还没有给出更多,但我不确定哪些细节会有所帮助。

更新:我尝试在生产服务器上删除约束但它没有效果;我也不想放弃索引,因为我不确定后果可能是什么,我不想让生产比现在更不稳定。

奇怪的是,我尝试手动执行抛出错误的SQL,并且Oracle接受了insert语句(尽管我必须使用字符串文字将to_date()调用中的日期包装起来以绕过“ORA-01861:literal”与格式字符串“错误”不匹配。这可能会发生什么?

4 个答案:

答案 0 :(得分:3)

根据约束的名称PK_REGISTRATION_OWNERSHIP,您有主要密钥违规。如果这些数据库没有以锁步方式维护此数据,那么/某人已经将记录插入到生产数据库的registration_ownerships表中,company_ownership_id = 2& registration_id = 2920。 (我猜的是基于名字的具体细节)

如果生产数据库中需要存在此特定值集,

1)检查已经存在的内容不是您要插入的内容。如果是的话,你已经完成了。

2)如果您需要按原样插入样本数据,则需要修改现有数据&重新插入它(以及所有相关/引用记录),然后您可以插入您的值。

答案 1 :(得分:1)

如果您查询表并找不到匹配的行,则可能是以下原因之一:

  1. 会话正在尝试两次插入行。
  2. 另一个会话已插入行,但尚未提交。
  3. 另外,检查dev和prod之间唯一约束的状态是否相同。也许dev上的那个被标记为未经验证 - 检查dev上的索引是否存在并且是唯一索引(注意:在Oracle中,可以使用由非唯一索引验证的唯一约束) )。

答案 2 :(得分:0)

仔细查看约束的基础唯一索引。删除约束的原因并没有改变,因为索引仍然存在,而且它是一个唯一索引。以下内容告诉您两种环境中的索引是什么?两个索引都有效吗?两者都定义相同吗?它们都是独一无二的吗?

SELECT ai.table_name, ai.index_name, ai.uniqueness, aic.column_name, ai.status
  FROM all_constraints ac JOIN all_indexes ai ON (ac.index_name = ai.index_name)
                          JOIN all_ind_columns aic ON (ai.index_name = aic.index_name)
 WHERE ac.owner = 'YOUR_USER'
   AND ac.constraint_name = 'PK_REGISTRATION_OWNERSHIP'
 ORDER BY ai.index_name, column_position;

答案 3 :(得分:0)

碰巧的是,目录周围有一个“注册”模型的备用副本;即使它有一个不同的名称(“registrations_2349871.rb”或类似的东西)Rails运行所有模型功能(保存,验证等)两次,因此违反了键约束!我以前从未见过这样的行为。删除流氓文件解决了这个问题。