0

mysql テーブルの制約が必要です。テーブルには、「id」、「ref」、「from」、および「to」フィールドがあります。制約は、同じ 'ref' と重複する時間 (フィールド 'from' と 'to') を持つデータセットがないことを保証する必要があります。

SQL の場合: 次のステートメントは常に '0' を返す必要があります。

select count(*) 
from   `TABLE` d1 inner join `TABLE` d2 on 
       d1.`ref` = d2.`ref` and d1.`id` <> d2.`id` and 
       d1.`to` >= d2.`from` and d1.`from`<=d2.`to`

これを制約で処理する方法はありますか?

4

2 に答える 2

0

「これを制約で処理する方法はありますか?」

はい、SQL Standard 2011 は、読み取り可能な宣言的な方法でこの種のシナリオをサポートしています。

ユニーク制約定義

<without overlap specification> ::=
<application time period name>  WITHOUT OVERLAPS

あなたの例では:

CREATE TABLE tab (
  id INT AUTO_INCREMENT PRIMARY KEY,
  ref VARCHAR(100),
  from_date DATE,
  end_date DATE,
  PERIOD FOR ref_period(from_date, end_date),
  UNIQUE (ref, ref_period WITHOUT OVERLAPS)
);

サンプル挿入:

INSERT INTO tab(ref, from_date, end_date) VALUES ('a', '2020-01-01','2020-03-01');
-- OK

INSERT INTO tab(ref, from_date, end_date) VALUES ('a', '2020-03-01','2020-05-01');
-- OK

INSERT INTO tab(ref, from_date, end_date) VALUES ('a', '2020-04-01','2020-07-01')
-- Duplicate entry 'a-2020-07-01-2020-04-01' for key 'ref

SELECT * FROM tab;

db<>fiddle デモ - Maria DB 10.5

于 2020-06-25T19:28:48.857 に答える
0

今、私は次のトリガーを持っています。ご協力いただきありがとうございます!

DELIMITER $$

USE `devtestplandb`$$

CREATE
TRIGGER `db`.`trig1`
BEFORE INSERT ON `db`.`TABLE`
FOR EACH ROW
BEGIN
    SET @CNT = (
            select  count(*) 
            from    `TABLE` d 
            where   d.`ref` = NEW.`ref` and 
                    d.`to` >= NEW.`from` and 
                    d.`from` <= NEW.`to`);
    IF @CNT != 0 THEN
        CALL error_001();
    END IF;
END$$

CREATE
TRIGGER `db`.`trig2`
BEFORE UPDATE ON `db`.`TABLE`
FOR EACH ROW
BEGIN
    SET @CNT = (
            select  count(*) 
            from    `TABLE` d 
            where   d.`ref` = NEW.`ref` and 
                    d.`ID` <> NEW.`ID` and
                    d.`to` >= NEW.`from` and 
                    d.`from` <= NEW.`to`);
    IF @CNT != 0 THEN
        CALL error_002();
    END IF;
END$$
于 2012-05-14T10:29:23.447 に答える