这个SQL约束可以更简单地编写吗?

时间:2012-03-24 20:19:51

标签: sql constraints h2

澄清 - 表中最多有4个不同的玩家,由他们的ID引用。我想强制执行此操作,即没有两个ID是相同的。

此外,由于最多4名玩家,有些可能为空。可能有很多这样的空值是一个坏主意吗?我不认为这样做,但只是为了确定,null == null是否会返回false?

...
CHECK (playerid1 <> playerid2)
  AND (playerid1 <> playerid3)
  AND (playerid1 <> playerid4)
  AND (playerid2 <> playerid3)
  AND (playerid2 <> playerid4)
  AND (playerid3 <> playerid4)
...

谢谢!

2 个答案:

答案 0 :(得分:10)

我会为此单独使用表格:

 create table game_players (
      game_id number, player_id number, player_position number
    );

然后你可以添加

  • 对game_id +玩家ID的UNIQUE约束(强制玩家每场比赛不会超过一次)
  • game_id + player_position的UNIQUE约束(确保一个位置最多只占一个玩家)
  • 对于执行它的player_position的CHECK约束只有值1,2,3或4

这应该以更清洁(IMHO)的方式达到你想要的效果。

答案 1 :(得分:1)

在你的七个表达中,你有重复,例如(playerid1 <> playerid2)。最终集限制为六个。

我希望有六个不同的约束,每个约束都有一个有意义的名称,以便向用户提供细粒度的错误消息,例如

CONSTRAINT playerid2__duplicates__playerid1 CHECK ( playerid1 <> playerid2 ),
CONSTRAINT playerid3__duplicates__playerid1 CHECK ( playerid1 <> playerid3 ),
CONSTRAINT playerid4__duplicates__playerid1 CHECK ( playerid1 <> playerid4 ),
CONSTRAINT playerid3__duplicates__playerid2 CHECK ( playerid2 <> playerid3 ),
CONSTRAINT playerid4__duplicates__playerid2 CHECK ( playerid2 <> playerid4 ),
CONSTRAINT playerid4__duplicates__playerid3 CHECK ( playerid3 <> playerid4 )

可能有兴趣透露我使用SQL编写了上述内容:

WITH T 
     AS
     (
      SELECT * 
        FROM (
              VALUES ('playerid1'), 
                     ('playerid2'), 
                     ('playerid3'),
                     ('playerid4')
             ) AS T (c)
     )
SELECT 'CONSTRAINT ' 
       + T2.c + '__duplicates__' + T1.c 
       + ' CHECK ( ' + T1.c + ' <> ' + T2.c + ' ),'
  FROM T AS T1, T AS T2
 WHERE T1.c < T2.c;