установить диапазон для столбца - PullRequest
2 голосов
/ 10 октября 2011

Я использую в своей базе данных много полей определенного диапазона, например:

CREATE TABLE figures (
    deg FLOAT,-- between 0 and pi
    prc FLOAT,-- between 0 and 1
    .......
);
CREATE TRIGGER filter1 BEFORE UPDATE ON figures FOR EACH ROW SET
    NEW.deg=IF(NEW.deg>3.1415926 OR NEW.deg<0, OLD.deg,NEW.deg),
    NEW.prc=IF(NEW.prc>1 OR NEW.prc<0, OLD.prc,NEW.prc),
    ..........;
CREATE TRIGGER filter2 BEFORE INSERT ON figures FOR EACH ROW SET
    NEW.deg=IF(NEW.deg>3.1415926 OR NEW.deg<0, NULL,NEW.deg),
    NEW.prc=IF(NEW.prc>1 OR NEW.prc<0, NULL,NEW.prc),
    .........;

Есть ли способ написать это более четко?
Что-то вроде:

--CREATE PROCEDURE/FUNCTION between()..................
CREATE TABLE figures (
    deg FLOAT between(0,3.1415),
    prc FLOAT between(0,1),
    .......

По крайней мере, я не хочу писать каждый фильтр дважды.(При вставке, при обновлении)

Ответы [ 4 ]

2 голосов
/ 10 октября 2011

Триггеры на данный момент являются лучшим решением.

Re: проверка ограничений ...

'Предложение CHECK анализируется, но игнорируется всеми механизмами хранения.'.

'Причиной принятия, но игнорирования синтаксических предложений является совместимость, упрощение переноса кода с других SQL-серверов и запуск приложений, создающих таблицы со ссылками.'

поднял прямо из: http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

1 голос
/ 10 октября 2011

Лучшее решение - использовать ограничение CHECK (), но MySQL не поддерживает ограничения CHECK (). (MySQL их анализирует, а затем игнорирует.)

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

Это оставляет триггеры. В вашем случае лучше всего использовать триггер, который вызывает сохраненную функцию.

1 голос
/ 10 октября 2011

По крайней мере, я не хочу писать каждый фильтр дважды.(ON INSERT, ON UPDATE)

Вы можете написать сохраненную функцию и вызвать ее в своем триггере.

DELIMITER $$

CREATE FUNCTION check_deg (degree FLOAT, olddegree FLOAT) RETURNS FLOAT
BEGIN
  DECLARE result FLOAT;
  result = IF(degree>3.1415926 OR degree <0, olddegree,degree);
  RETURN result;
END$$

DELIMITER ;

Таким образом, у вас есть одна точка, в которой определены пределыесли что-то меняется, вам нужно изменить границы только в одном месте.

0 голосов
/ 11 октября 2011

У меня есть незаконченная идея:

CREATE PROCEDURE check_constraint (table VARCHAR,field VARCHAR,condition VARCHAR)
BEGIN
    SET @update_trigger = CONCAT ("
        IF EXIST TRIGGER check_constraint_",table,"_",field,"
        BEGIN /*I don't know yet what to do*/ END
        ELSE /*IF TRIGGER DONT EXIST*/
        BEGIN
            CREATE TRIGGER check_constraint_",table,"_",field,"
            BEFORE UPDATE ON ",table," FOR EACH ROW SET
            NEW.",field,"=IF("condition, ", OLD.",field,",NEW.",field,");
        END
    ");
    PREPARE update_trigger FROM @update_trigger;
    EXECUTE update_trigger;
    DEALLOCATE PREPARE update_trigger;
    SET @insert_trigger = ..............................
END

После того, как у нас есть законченная функция, мы можем просто вызвать ее при создании базы данных:

CALL check_constraint("table","field","NEW.field<34567");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...