当前位置: 首页 > 面试题库 >

在Oracle中的Check语句中使用子查询

宰父飞翼
2023-03-14
问题内容

所以我试图解决这个问题,但似乎最后一行(检查)不允许在其中进行子查询。有什么办法可以使Oracle工作吗?

CREATE TABLE Tank (
    n_id            int,
    day             date,
    level           int,
    CONSTRAINT pk_w_td PRIMARY KEY (n_id,day),
    CONSTRAINT fk_w_td_tan FOREIGN KEY (n_id) REFERENCES Tanks ON DELETE CASCADE,
    CHECK (level > 0 AND level <= (SELECT capacity FROM Tanks WHERE Tanks.n_id = TanksDay.n_id))
);

这是错误信息:

Error at Command Line:7 Column:32 Error report: SQL Error: ORA-02251: subquery not allowed here
02251. 00000 -  "subquery not allowed here"
*Cause:    Subquery is not allowed here in the statement.
*Action:   Remove the subquery from the statement.

问题答案:

由于CHECK约束不能基于查询,因此有三种基本方法可以解决此类问题。

选项1:触发器

最简单的方法是在TANK上放置一个触发器,以查询TANKS并在LEVEL超过CAPACITY时引发异常。但是,这种简单化方法的问题在于,几乎不可能正确处理并发问题。如果会话1降低了容量,则会话2增加了LEVEL,然后两个事务都提交,触发器将无法检测到违规。如果很少修改一个或两个表,这可能不是问题,但总的来说,这将是一个问题。

选项2:实例化视图

您可以通过创建连接TANK和TANKS表的ON COMMIT实例化视图,然后在该实例化视图上创建一个CHECK约束来验证LEVEL <=
CAPACITY来解决并发问题。您还可以通过使实例化视图仅包含违反约束的数据来避免将数据存储两次。这将需要两个基表上的物化视图日志,这将增加插入的开销(尽管比使用触发器要少)。将检查推送到提交时间将解决并发问题,但由于COMMIT操作现在可能由于物化视图刷新失败而失败,因此引入了一些异常管理问题。您的应用程序需要能够处理该问题并向用户发出警告。

选项3:更改数据模型

如果表A中的值取决于表B中的限制,则可能表明表B中的限制应为表A的属性(而不是表B的属性或除了表B的属性外)。当然,这取决于数据模型的细节,但是通常值得考虑。



 类似资料:
  • 问题内容: 给定一个表名和一个列名,我试图动态删除一个我事先不知道名称的Oracle约束。 我可以通过以下查询找到约束名称: 我的第一个想法是使用子查询,但这不起作用,并导致ORA-02250错误: 到目前为止,我唯一可行的解​​决方案是以下解决方案,但感觉不必要的复杂: 是否有一种方法可以像我最初打算的那样使用子查询来做到这一点?如果不是,那么有人可以建议一种更简洁的方法吗? 问题答案: 你不能

  • 问题内容: 我到处都在寻找解释,以了解选择语句中的子查询如何工作,但由于解释非常模糊,我仍然无法理解该概念。 我想知道您如何在oracle的select语句中使用子查询以及它的确切输出。 例如,如果我有一个查询,希望显示这些表中员工的姓名及其管理的个人资料数量 员工(EmpName,EmpId) Profile(ProfileId,…,EmpId) 如何使用子查询? 我当时想在select语句中需

  • 问题内容: 在WHERE子句中有使用SELECT语句描述的名称吗?这是好/不好的做法吗? 这会是更好的选择吗? 它远没有那么优雅,但是运行起来比以前的版本要快。我不喜欢它,因为它在GUI中没有非常清晰地显示(并且SQL初学者需要理解它)。我可以将其分为两个独立的查询,但是随后事情变得混乱了…… 注意:我不仅需要日期和分数(例如姓名) 问题答案: 称为相关子查询。它有它的用途。

  • 我想在使用jpa条件的查询中显示父子关系。但是我一直在学习如何设置通过表达式连接 其中,transquery是由具有多个选择和多个联接的criteriaQuery生成的 我想如下所示显示父事务及其子事务,但在条件查询中使用

  • 本文向大家介绍Oracle中死事务的检查语句,包括了Oracle中死事务的检查语句的使用技巧和注意事项,需要的朋友参考一下 查询v$px_session和v$fast_start_servers,显示很多并行进程在rollback,根据以往的工程经验: 于是改为 之后,再次运行 使用如下脚本查看回滚完毕的预计时间(以天为单位): 24*0.21=5.04小时。即:预计5.04小时后回滚完毕。 另外

  • 我正在尝试在pyspark中运行子查询。我发现可以使用SQL语句。但是,使用“where”或“filter”操作是否有任何内在的支持? 考虑测试数据框架: 在这里,您可以看到where函数工作正常。当我尝试使用子查询执行相同操作时,如下所示: 我得到这个错误: 属性错误回溯(最近一次调用)在---- /opt/cloudera/parcels/CDH-6.3.4-1。cdh6.3.4。p4744.