Rails: нарушение ограничений Oracle - PullRequest
5 голосов
/ 12 апреля 2010

Я занимаюсь обслуживанием сайта Rails, который унаследовал; он управляется базой данных Oracle, и у меня есть доступ как к разработке, так и к производственной установке сайта (каждая со своей собственной базой данных Oracle). Я сталкиваюсь с ошибкой 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 принял оператор вставки (хотя мне пришлось обернуть даты в вызовах to_date () строковыми литералами, чтобы обойти "ORA-01861: literal" не соответствует строке формата "ошибка). Что здесь может происходить?

Ответы [ 4 ]

3 голосов
/ 12 апреля 2010

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

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

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

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

1 голос
/ 13 апреля 2010

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

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

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

0 голосов
/ 20 апреля 2010

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

0 голосов
/ 14 апреля 2010

Внимательно посмотрите на базовый уникальный индекс для ограничения. Причина, по которой снятие ограничения ничего не меняет, заключается в том, что индекс остается, и это уникальный индекс. Что ниже говорит вам об индексах в обеих средах? Оба индекса действительны? Оба определены одинаково? Они оба на самом деле уникальны?

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;
...