Oracle Database Enforce CHECK для нескольких таблиц - PullRequest
6 голосов
/ 11 апреля 2010

Я пытаюсь применить ограничение CHECK в базе данных ORACLE для нескольких таблиц

CREATE TABLE RollingStocks ( 
  Id NUMBER,
  Name Varchar2(80) NOT NULL,           
  RollingStockCategoryId NUMBER NOT NULL,            
  CONSTRAINT Pk_RollingStocks Primary Key (Id),
  CONSTRAINT Check_RollingStocks_CategoryId  
  CHECK ((RollingStockCategoryId  IN (SELECT Id FROM FreightWagonTypes)) 
        OR 
        (RollingStockCategoryId  IN (SELECT Id FROM LocomotiveClasses)))       
);

... но я получаю следующую ошибку:

* Причина: подзапрос здесь запрещен. * Действие: удалить подзапрос из оператора.

Можете ли вы помочь мне понять, в чем проблема или как достичь того же результата?

Ответы [ 3 ]

2 голосов
/ 11 апреля 2010

То, что вы пытаетесь сделать, это убедиться, что значения, вставленные в одну таблицу, существуют в другой таблице, то есть принудительно использовать внешний ключ. Так что это будет:

CREATE TABLE RollingStocks ( 
...

  CONSTRAINT Pk_RollingStocks Primary Key (Id),
  CONSTRAINT RollingStocks_CategoryId_FK (RollingStockCategoryId )
     REFERENCES FreightWagonTypes (ID)      
);  

За исключением того, что вы хотите применить внешний ключ, который ссылается на две таблицы. Это не может быть сделано.

У вас есть несколько вариантов. Можно было бы объединить FreightWagonTypes и LocomotiveClasses в одну таблицу. Если вам нужны отдельные таблицы для других частей вашего приложения, вы можете создать материализованное представление для обеспечения применения внешнего ключа. Материализованные представления похожи на таблицы и могут ссылаться на внешние ключи. Эта опция не будет работать, если значения ключей для двух таблиц конфликтуют.

Другим вариантом является признание того, что наличие двух возможных ссылочных таблиц предполагает, что RollingStock, возможно, необходимо разделить на две таблицы - или, возможно, три: таблицы супертипа и две подтипы, то есть RollingStock и FreightWagons, Locomotives.

Кстати, а как насчет пассажирских вагонов, вагонов-охранников и вагонов-ресторанов?

2 голосов
/ 11 апреля 2010

Проверьте ограничения очень ограничены в Oracle. Чтобы выполнить проверку, как вы предлагаете, вам нужно реализовать PL / SQL триггер .

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

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

К сожалению, Oracle не поддерживает сложные проверочные ограничения.

В этом случае лучшим вариантом будет немного изменить модель данных - добавить родительскую таблицу вместо FreightWagonTypes и LocomotiveClasses, в которой будут храниться все идентификаторы из обеих этих таблиц. Таким образом, вы можете добавить FK в одну таблицу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...