【问题标题】:MySQL constraint based on previous row value基于前一行值的 MySQL 约束
【发布时间】:2018-06-23 18:02:52
【问题描述】:

我有 2 张桌子:

表 A:

AID
1
2
3
4

表 B:

BID AID Status
1   1   Open
2   2   Open
3   3   Closed
4   1   Open - don't allow this row until AID 1 Status changes to closed
5   2   Open - don't allow this row until AID 2 Status changes to closed
6   3   Open - allow this row because AId 3 Status is closed
7   3   Open - don't allow this row until AID 3 Status changes to closed

如何约束在 B 表中添加另一行,直到我将 AID 的状态更改为已关闭。 或者我应该将状态列移动到 A 表?但即便如此,我如何在 B 表中检查 A 行的状态?

【问题讨论】:

  • MySQL 不强制检查约束。然后,您的选择包括使用触发器和/或存储过程。
  • ..或将逻辑构建到插入中
  • 如果辅助 4 不存在,是否允许插入状态为关闭的?
  • 是的,如果 AID 4 尚未使用,则应视为已关闭
  • 将逻辑构建到插入中是最好的方法还是使用触发器/存储过程?

标签: mysql constraints check-constraint


【解决方案1】:

通过演示的方式:

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(BID SERIAL PRIMARY KEY
,AID INT NOT NULL
,Status VARCHAR(12) NOT NULL
);

INSERT INTO my_table VALUES
(1,1,'Open'),
(2,2,'Open'),
(3,3,'Closed');

SELECT * FROM my_table;
+-----+-----+--------+
| BID | AID | Status |
+-----+-----+--------+
|   1 |   1 | Open   |
|   2 |   2 | Open   |
|   3 |   3 | Closed |
+-----+-----+--------+

INSERT INTO my_table (aid,status) 
SELECT 1
     , 'Open' 
  FROM (SELECT 1) x 
  LEFT 
  JOIN 
     ( SELECT a.* 
         FROM my_table a 
         JOIN 
            ( SELECT aid
                   , MAX(bid) bid 
                FROM my_table 
               GROUP  
                  BY aid
            ) b
           ON b.aid = a.aid
          AND b.bid = a.bid
      ) y
     ON y.aid = 1
    AND y.status = 'Open'
  WHERE y.bid IS NULL;

+-----+-----+--------+
| BID | AID | Status |
+-----+-----+--------+
|   1 |   1 | Open   |
|   2 |   2 | Open   |
|   3 |   3 | Closed |
+-----+-----+--------

INSERT INTO my_table (aid,status) VALUES
(1,'Closed');

SELECT * FROM my_table;
+-----+-----+--------+
| BID | AID | Status |
+-----+-----+--------+
|   1 |   1 | Open   |
|   2 |   2 | Open   |
|   3 |   3 | Closed |
|   4 |   1 | Closed |
+-----+-----+--------+

INSERT INTO my_table (aid,status) 
SELECT 1
     , 'Open' 
  FROM (SELECT 1) x 
  LEFT 
  JOIN 
     ( SELECT a.* 
         FROM my_table a 
         JOIN 
            ( SELECT aid
                   , MAX(bid) bid 
                FROM my_table 
               GROUP  
                  BY aid
            ) b
           ON b.aid = a.aid
          AND b.bid = a.bid
      ) y
     ON y.aid = 1
    AND y.status = 'Open'
  WHERE y.bid IS NULL;

SELECT * FROM my_table;
+-----+-----+--------+
| BID | AID | Status |
+-----+-----+--------+
|   1 |   1 | Open   |
|   2 |   2 | Open   |
|   3 |   3 | Closed |
|   4 |   1 | Closed |
|   5 |   1 | Open   |
+-----+-----+--------+

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 2013-05-05
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多