Sql Oracle数据库对多个表强制检查

Sql Oracle数据库对多个表强制检查,sql,oracle,Sql,Oracle,我试图在ORACLE数据库中对多个表强制执行检查约束 CREATE TABLE RollingStocks ( Id NUMBER, Name Varchar2(80) NOT NULL, RollingStockCategoryId NUMBER NOT NULL, CONSTRAINT Pk_RollingStocks Primary Key (Id), CONSTRAINT Check_RollingStocks_Cate

我试图在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)))       
);
…但我得到以下错误:

*原因:语句中此处不允许子查询。 *操作:从语句中删除子查询


您能帮助我了解问题所在或如何实现相同的结果吗?

检查约束在Oracle中非常有限。要执行您建议的检查,您必须实现一个


我的建议是完全避免触发。实现一个修改数据库并包含检查的存储过程。存储过程更易于维护,但实现起来稍微困难一些。但是,从长远来看,将前端从直接表访问更改为存储过程访问会有很多回报。

您尝试的是确保插入到一个表中的值存在于另一个表中,即强制执行外键。这就是:

CREATE TABLE RollingStocks ( 
...

  CONSTRAINT Pk_RollingStocks Primary Key (Id),
  CONSTRAINT RollingStocks_CategoryId_FK (RollingStockCategoryId )
     REFERENCES FreightWagonTypes (ID)      
);  
除了要强制执行引用两个表的外键之外。这是不可能做到的

你有两个选择。一种是将货车类型和机车类合并到一个表中。如果应用程序的其他部分需要单独的表,那么可以构建一个物化视图来强制执行外键。物化视图类似于表,可以被外键引用。如果两个表的键值冲突,此选项将不起作用

另一种选择是认识到存在两个候选参考表表明,滚动轴承可能需要分为两个表-或者三个:一个超级型和两个子型表,即滚动轴承和货车、机车


顺便问一下,客货两用车、警卫车和餐厅车呢?

不幸的是,Oracle不支持这样复杂的检查约束


在这种情况下,最好的选择是稍微更改数据模型—在
FreightWagonTypes
MotorveClass
上添加一个父表,这将保存这两个表中的所有ID。通过这种方式,您可以将FK添加到单个表。

另一种方法是将RollingStockCategoryId拆分为两个可为空的列,一个作为FK到FreightWagonTypes,另一个作为FK到MotorveClass。您可以添加一个检查约束,说明任何行的一个(并且只有一个)不能为null。