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

时间:2017-07-17 11:34:54

标签: sql database oracle plsql triggers

这是我的表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。

1 个答案:

答案 0 :(得分:2)

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文档