2010-04-12 4 views
5

Я занимаюсь обслуживанием на сайте Rails, который я унаследовал; это связано с базой данных Oracle, и у меня есть доступ как к разработке, так и к производственным установкам сайта (каждый со своей собственной БД Oracle). Я бегу в ошибку Oracle при попытке вставить данные на производственном участке, но не на сайте Dev:Rails: нарушение ограничений 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). Пожалуйста, дайте мне знать, если вам нужна дополнительная информация для устранения неполадок. Мне жаль, что я уже не дал больше, но я просто не был уверен, какие детали будут полезны.

UPDATE: Я попытался удалить ограничение на производственном сервере, но это не повлияло; Я тоже не хотел отказываться от индекса, потому что я не уверен, каковы могут быть последствия, и я не хочу делать продукцию менее стабильной, чем она есть.

Любопытно, что я попытался выполнить вручную SQL, который выдавал ошибку, и Oracle принял инструкцию insert (хотя мне пришлось переносить даты в вызовы to_date() со строковыми литералами, чтобы обойти «ORA-01861: literal не соответствует строке формата "error". Что может быть здесь?

ответ

0

Как это случилось, была запасная копия модели «регистрации», лежащей вокруг каталога; даже несмотря на то, что у него другое имя («registrations_2349871.rb» или что-то в этом роде) Rails запускала все функциональные возможности модели (сохранение, проверка и т. д.) дважды, отсюда и ограничение ограничения ключа! Раньше я никогда не видел такого поведения. Удаление файла-изгоев решило проблему.

3

Основываясь на названии ограничения, PK_REGISTRATION_OWNERSHIP, у вас есть нарушение первичного ключа. Если эти базы данных не поддерживают эти данные в блокировке, что-то/кто-то уже вставил запись в таблицу registration_ownerships в вашу производственную базу данных с помощью company_ownership_id = 2 & registration_id = 2920. (Я предполагаю, что на специфику на основе имен)

Если этот конкретный набор значений должен существовать в базе данных производства,

1) проверить, что там уже не то, что вы пытаетесь вставить. если да, то все готово.

2) Если вы необходимости для вставки данных образцов как есть, вам необходимо изменить существующие данные & повторно вставить его (и все зависимые/Отсносящиеся записи), то вы можете вставить свои значения.

+0

Спасибо за отзыв, Дейв. Я запустил select where company_ownership_id = 3 и registration_id = 2920 в производственной базе данных, и я не получил никаких записей. registration_id - это первый первичный ключ, а company_ownership_id - второй в registration_ownerships ... может быть, есть еще одна причина, по которой я получаю ошибку? Или я просто вас не понимаю? – justinbach

+0

Ну, я догадался о компонентах первичного ключа на основе имен. Вы, вероятно, хотите посмотреть на определение PK_REGISTRATION_OWNERSHIP напрямую, чтобы узнать, что именно в базе данных думает уникальное значение. Является ли это единственным заявлением, которое терпит неудачу, или частью партии, где у вас могут быть дубликаты? – DaveE

+0

Это единственная вставка, которая терпит неудачу, хотя она является частью набора запросов на вставку (регистрация_владений является частью модели регистрации). Ваша догадка была хорошей; определение PK_REGISTRATION_OWNERSHIP состоит из registration_id и company_ownership_id как поля и связано с таблицей registration_ownerships. Каждая из двух идентификаторов соответствует определенной последовательности. Может ли быть, что записи, используемые в таблице с этой комбинацией атрибутов, были удалены, но Oracle отметила, что определенная комбинация клавиш используется как «используется»? – justinbach

1

Если запрос таблицы и не найти соответствующих строк, то один из следующих может быть причиной:

  1. Сеанс пытается вставить строку дважды.
  2. Другая сессия вставила строку, но еще не зафиксирована.

Кроме того, убедитесь, что состояние уникального ограничения одинаково между dev и prod. Возможно, тот, что на dev отмечен как не проверенный, - проверьте, что индекс существует на dev и является индексом (обратите внимание: в Oracle возможно иметь уникальное ограничение, подтвержденное неидеальным индексом).

+0

Джеффри, насколько я могу судить, индекс идентичен по производству и dev; оба являются действительными и уникальными. Кодовые базы также идентичны между dev и production (за вычетом некоторых данных конфигурации, таких как учетные данные БД), поэтому я предполагаю, что если бы это была двойная вставка сеанса или конфликт фиксации, я бы увидел это на обеих установках. Есть ли что-нибудь еще, что может вызвать это? – justinbach

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; 
+0

DCookie, спасибо за ответ. Обе среды дают точно такие же результаты для запроса; а именно, что оба индекса являются уникальными, действительными и точно определены. Что еще может быть причиной этого? – justinbach

Смежные вопросы