繁体   English   中英

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

[英]Can this SQL constraint be written more simply?

需要说明的是-表中最多有4个不同的玩家,由其ID引用。 我要强制执行此操作,即没有两个ID相同。

另外,由于最多可容纳4位玩家,因此有些玩家可能为空。 可能有很多这样的null是个坏主意吗? 我不认为这样做,但是可以肯定的是, null == null返回false?

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

谢谢!

我为此使用一个单独的表:

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

然后您可以添加

  • 一个对game_id + player id的唯一约束(要强制一个玩家每次游戏都不会出现多次)
  • 一个对game_id + player_position的唯一约束(以确保一个位置最多被一个玩家占据)
  • 用于player_position强制执行的CHECK约束只有值1、2、3或4

这应该以某种更简洁的方式(IMHO)实现您想要的。

在您的七个表达式中,您有重复的内容,例如(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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM