Oracle - Почему имя constraint_name должно быть уникальным, если оно принадлежит другой схеме?

В Oracle, если вы попытаетесь явно определить схему для ограничения в операторе CREATE TABLE, это приведет к ошибке ORA-00904: : invalid identifier:

CREATE TABLE SCHEMA1.MY_TABLE
(
  TABLE_ID NUMBER(5)
, FLAG VARCHAR2(1) DEFAULT 'F'
, CONSTRAINT SCHEMA1.MY_TABLE_PK PRIMARY KEY (TABLE_ID)  -- Parser doesn't like 'SCHEMA1'
, CONSTRAINT SCHEMA1.MY_TABLE_FLAG_CK CHECK (FLAG IN ('T', 'F')) --Same issue
);

В этом нет ничего страшного, потому что ограничение OWNER по умолчанию соответствует той же схеме, которая определена в объявлении CREATE TABLE (или, по крайней мере, в схеме, в которую вы вошли - у моих учетных записей нет прав на проверку) . Это можно подтвердить, подняв ограничение в ALL_CONSTRAINTS или DBA_CONSTRAINTS и просмотрев значение OWNER (которое будет читать SCHEMA1 для двух вышеуказанных ограничений).

Но если вы затем дополните это утверждение вторым повторяющимся утверждением в другой схеме:

CREATE TABLE SCHEMA2.MY_TABLE
(
  TABLE_ID NUMBER(5)
, FLAG VARCHAR2(1) DEFAULT 'F'
, CONSTRAINT MY_TABLE_PK PRIMARY KEY (TABLE_ID)          --This constraint already exists
, CONSTRAINT MY_TABLE_FLAG_CK CHECK (FLAG IN ('T', 'F')) --This one too
);

это приводит к ORA-00955: name is already used by an existing object ошибке.

Насколько я понимаю, ограничения - это просто еще один объект в базе данных, который, как я предполагал, подчиняется тем же правилам владения, с которыми я знаком. Но из приведенного выше поведения ясно, что они не ведут себя как большинство объектов в базе данных.

Вопросы

  • Что такого особенного в ограничениях, что требует, чтобы их имена были уникальными для всех схем (в отличие от других объектов в базе данных)?
  • Кто-нибудь знает техническую причину этого требования к именованию?

Для контекста, я столкнулся со сценарием на работе, где я хотел хранить повторяющиеся имена в разных схемах (не спрашивайте ... это унаследованное дублирование, и я просто пытаюсь остаться последовательны, пока у меня не будет средств на рефакторинг). Теперь я понимаю, что могу очень просто добавить схему к имени и быстро обойти эту проблему, но это неправильно меняет мой ОКР, поэтому я хотел бы лучше понять, почему я не могу делать то, что пытаюсь сделать. .

----------------------------- ОБНОВЛЕНИЕ ----------------- ----------

Ладно ... так что я дурак. Обратите внимание, что описанный выше сценарий невозможно повторить в чистой среде. После попытки воспроизвести проблему я теперь понимаю, что произошло.

В настоящее время я работаю над очисткой некоторых операторов DDL в рамках подготовки к производственному выпуску. Я не единственный разработчик в этой среде, и моя оффшорная команда работала над этими же столами. Я редактировал некоторые уже существующие сценарии DDL при подготовке к производственной версии и добавил некоторые необходимые ограничения к нескольким операторам CREATE TABLE.

Похоже, что мне не удалось запустить свои DROP сценарии до выполнения второго оператора в SCHEMA2. Мое замешательство было вызвано тем, что я думал, что получаю ошибку ORA-00955 из-за новых ограничений, которые я добавлял, хотя на самом деле это было потому, что SCHEMA2.MY_TABLE уже существовала в этой среде. Этот неправильный диагноз усугубился тем, что я изменил имена ограничений и затем успешно повторно запустил все мои сценарии (так как перед повторным тестированием я должен был запустить свои DROP операторы во всех схемах). В результате я подумал, что заметил непредвиденное поведение, хотя на самом деле этого не произошло.

Спасибо всем, кто прокомментировал, что показал мне свет!


person DanK    schedule 09.03.2016    source источник
comment
Это не так - вы можете создавать ограничения с одинаковыми именами в разных схемах. Поэтому не уверен, что вы делаете - я действительно не понял, когда вы сказали (или, по крайней мере, в схеме, в которую вы вошли - у моих учетных записей нет прав на проверку).   -  person Tony Andrews    schedule 09.03.2016
comment
Собирался прокомментировать то же самое, что и у нас есть экземпляры с несколькими учетными записями разработчиков с идентичными таблицами / ограничениями. Все работает чисто, если вы правильно вошли в схему, в которой ее создаете.   -  person Michael Broughton    schedule 09.03.2016
comment
Я не использую свою БД, но возможен ли сбой, при котором включение создания ограничения внутри таблицы создания по умолчанию устанавливает право собственности на вошедшего в систему пользователя, а не на схему, указанную для таблицы? Это могло вызвать коллизию, но ее можно разрешить, сделав ограничение отдельным оператором create. Я всегда делаю свои создания, входящие в систему с использованием правильной схемы, поэтому никогда не сталкивался с этой проблемой ..   -  person Michael Broughton    schedule 09.03.2016
comment
@TonyAndrews - Хм ... Я только что попробовал другой тест, и вы абсолютно правы ... Теперь я по-настоящему ломаю голову ... Позвольте мне просмотреть свои оригинальные скрипты, и я обновлю пост, как только Я могу воссоздать то, что видел раньше.   -  person DanK    schedule 09.03.2016
comment
@TonyAndrews Спасибо за ваш комментарий ... Думаю, я знаю, что произошло, и обновил свой вопрос.   -  person DanK    schedule 09.03.2016
comment
@MichaelBroughton Спасибо за ваш комментарий ... это определенно был сбой, но не в Oracle ... Я списал это на ошибку пользователя с моей стороны и приложил объяснение того, что, как я думаю, произошло.   -  person DanK    schedule 09.03.2016


Ответы (1)


В вашем вопросе не хватает пользователя, под которым вы запускаете скрипт. Но вот небольшой эксперимент. Подключен к базе данных как пользовательская система. У меня есть схемы NGM42 и NGM41, доступные для эксперимента.

CREATE TABLE NGM41.MY_TABLE
(
  TABLE_ID NUMBER(5)
, FLAG VARCHAR2(1) DEFAULT 'F'
, CONSTRAINT MY_TABLE_PK PRIMARY KEY (TABLE_ID)  -- Parser doesn't like 'SCHEMA1'
, CONSTRAINT MY_TABLE_FLAG_CK CHECK (FLAG IN ('T', 'F')) --Same issue
);

CREATE TABLE NGM42.MY_TABLE
(
  TABLE_ID NUMBER(5)
, FLAG VARCHAR2(1) DEFAULT 'F'
, CONSTRAINT MY_TABLE_PK PRIMARY KEY (TABLE_ID)  
, CONSTRAINT MY_TABLE_FLAG_CK CHECK (FLAG IN ('T', 'F')) 
);

Оба утверждения выполняются успешно. Так что же случилось с ограничениями?

select owner,constraint_name from all_constraints
where constraint_name in ('MY_TABLE_PK','MY_TABLE_FLAG_CK')

NGM42   MY_TABLE_PK
NGM41   MY_TABLE_PK
NGM41   MY_TABLE_FLAG_CK
NGM42   MY_TABLE_FLAG_CK

Ограничения создаются в той же схеме, что и таблица. Как видите, они не обязательно должны быть глобально уникальными в базе данных.

person Rene    schedule 09.03.2016
comment
Спасибо за этот ответ ... он мертв. Казалось бы, моя среда не была чистой до того, как я попытался запустить свой второй оператор. Мой ORA-00955 возник из-за уже существующей таблицы, а не из-за ограничения. - person DanK; 09.03.2016