如何在 sql 中使用子查询创建约束?

Posted

技术标签:

【中文标题】如何在 sql 中使用子查询创建约束?【英文标题】:How can I create constraint using subquery in sql? 【发布时间】:2017-07-17 11:34:54 【问题描述】:

这是我的桌子game

create table game (
    h_team number,
     a_team number,
     p_date date
);

要遵守的条件:每支球队在特定日期打一场比赛。基本上是锦标赛通常应该发生的正常规则。

我添加了以下约束:

我想添加另一个约束来限制添加以下查询执行的内容:

select h_team, p_date
from game
where (h_team,p_date) not in (select a_team,p_date from game);

select a_team, p_date
from game
where (a_team,p_date) not in (select h_team,p_date from game);

例如,假设该表中的记录是 (1,2,23-JAN-2000)。因此无法插入 (3,1,23-JAN-2000)、(2,4,23-JAN-2000) 等记录。谢谢!

我更喜欢 SQl,但似乎在 SQL 中是不可能的。那么它将如何使用 PL-SQL。

【问题讨论】:

我删除了不兼容的数据库标签。请仅使用您真正使用的数据库进行标记。 您尝试过使用子查询吗?发生了什么? Using subquery in a Check statement in Oracle的可能重复 您不能在约束中使用查询。你能用语言解释你想要强制或阻止的场景吗? @WilliamRobertson 假设该表中的记录是 (1,2,23-JAN-2000)。因此无法插入 (3,1,23-JAN-2000)、(2,4,23-JAN-2000) 等记录。 【参考方案1】:

SQL 断言

您正在寻找的功能称为 SQL 断言,and it's not yet implemented in Oracle 12c。同时,按照您自己的建议使用触发器。

你的触发器

当然,您的触发器不起作用,因为它的语法非常错误。

CREATE TRIGGER xx_game_trigger
BEFORE INSERT          -- This clause
ON xx_game             -- before this one
REFERENCING NEW AS new -- You'll probably need this
FOR EACH ROW
BEGIN
  -- There's no such thing as IF EXISTS in PL/SQL. Here's a workaround. This loop will run
  -- zero or one times.
  FOR rec IN (
    SELECT 1 FROM dual
    WHERE EXISTS (
      -- I'm assuming that you're interested in matches between existing records
      -- And the record you're about to insert (:new.xxx). Adapt accordingly
      SELECT 1 FROM xx_game WHERE (home_team,play_date) IN (:new.away_team,:new.play_date)
    )
    OR EXISTS (
      SELECT 1 FROM xx_game WHERE (away_team,play_date) IN (:new.home_team,:new.play_date)
    )
  )
  LOOP
    -- There's no TRANSACTION keyword here. But anyway, I'd rather raise an exception
    -- than roll back the transaction. That seems much cleaner to me.
    ROLLBACK;
  END LOOP;
END xx_game_trigger;

请考虑the complete CREATE TRIGGER syntax 的 Oracle 文档

【讨论】:

但是该代码给出了错误。你知道如何解决它吗? 嘿@Lukas!感谢你的努力,伙计。但我得到了同样的错误:ORA-04071: missing BEFORE, AFTER or INSTEAD OF keyword 04071. 00000 - "missing BEFORE, AFTER or INSTEAD OF keyword" *Cause: The trigger statement is missing the BEFORE/AFTER/INSTEAD OF clause. *Action: Specify either BEFORE, AFTER or INSTEAD OF. 您现在正在运行的确切语句是什么?

以上是关于如何在 sql 中使用子查询创建约束?的主要内容,如果未能解决你的问题,请参考以下文章

在oracle中如何使用sql语句创建默认约束

检查约束内的子查询

SQL主外键,子查询

如何在 sql server 2008 中获取没有约束的表列?

SQL主外键和子查询

如何证明在 SQL 中使用子选择查询会降低服务器的性能