SQLite: триггер для проверки вновь вставленной строки на соответствие ограничения в другой таблице - PullRequest
0 голосов
/ 08 мая 2020

У меня есть база данных со следующей схемой:

Sensors (
ID      INTEGER PRIMARY KEY AUTOINCREMENT
                UNIQUE
                NOT NULL,
SITE_ID INTEGER REFERENCES Sites (ID) 
                NOT NULL,
NAME    TEXT    UNIQUE
                NOT NULL
);

Sites (
ID   INTEGER PRIMARY KEY AUTOINCREMENT
             UNIQUE
             NOT NULL,
NAME TEXT    UNIQUE
             NOT NULL
);

Data (
SENSOR_ID INTEGER  REFERENCES Sensors (ID) 
                   NOT NULL,
COUNT     INTEGER  NOT NULL,
TIME      DATETIME NOT NULL,
TYPE      TEXT     NOT NULL,
VALUE     REAL     NOT NULL,
PRIMARY KEY (
    SENSOR_ID,
    COUNT,
    TIME,
    TYPE
)
);

Limits (
SITE_ID INTEGER REFERENCES Sites (ID) 
                NOT NULL,
TYPE    TEXT    NOT NULL,
HIGH    REAL    NOT NULL,
LOW     REAL    NOT NULL,
PRIMARY KEY (
    SITE_ID,
    TYPE
)
);

Данные содержат все данные для всех датчиков и сайтов. Данные имеют несколько разных типов. В ограничениях есть строка для каждого типа данных для каждого из сайтов. Я хочу создать таблицу, идентичную Data (называемую предупреждениями), содержащую только те строки, значение которых выходит за пределы в Limit.

Я хочу сделать это с помощью триггера, потому что пределы могут изменяться, а строки добавляются к данным время от времени.

Вот моя лучшая попытка:

CREATE TRIGGER VALUE_OUT_OF_RANGE 
AFTER INSERT
ON Data
WHEN NEW.VALUE < (SELECT Limits.LOW FROM Limits INNER JOIN Sensors ON (Sensors.SITE_ID = Limits.SITE_ID) WHERE (Sensors.ID = NEW.SENSOR_ID AND Limits.TYPE = NEW.TYPE))
BEGIN
    INSERT INTO Warnings(SENSOR_ID, COUNT, TIME, TYPE, VALUE) VALUES(NEW.SENSOR_ID, NEW.COUNT, NEW.TIME, NEW.TYPE, NEW.VALUE);
END;

В своей попытке я проверял только нижний предел, в последнем триггере я хотел бы проверить, что значение находится между НИЗКИЕ и ВЫСОКИЕ пределы. Я пробовал оператор Select отдельно и получаю данные, которые ищу. Любая помощь или предложение приветствуются.

1 Ответ

0 голосов
/ 08 мая 2020

Мне удалось найти решение, которое работает. Разместите на случай, если это кому-то поможет.

CREATE TRIGGER VALUE_OUT_OF_RANGE
    AFTER INSERT
    ON Data
    FOR EACH ROW
    WHEN NEW.VALUE < (
                           SELECT Limits.LOW
                             FROM Limits
                                  JOIN
                                  Sensors ON (Sensors.SITE_ID = Limits.SITE_ID) 
                            WHERE (Sensors.ID = NEW.Sensor_ID AND 
                                   Limits.TYPE = NEW.TYPE) 
                            LIMIT 1
                       )
    OR 
    NEW.VALUE > (
                           SELECT Limits.HIGH
                             FROM Limits
                                  JOIN
                                  Sensors ON (Sensors.SITE_ID = Limits.SITE_ID) 
                            WHERE (Sensors.ID = NEW.Sensor_ID AND 
                                   Limits.TYPE = NEW.TYPE) 
                            LIMIT 1
                       )
BEGIN
    INSERT INTO Warnings (
                         SENSOR_ID,
                         COUNT,
                         TIME,
                         TYPE,
                         VALUE
                     )
                     VALUES (
                         NEW.SENSOR_ID,
                         NEW.COUNT,
                         NEW.TIME,
                         NEW.TYPE,
                         NEW.VALUE
                     );
END;
...