LINUX.ORG.RU

PostgreSQL ограничения


0

0

При
Проблема в следующем:

есть таблица: 
\d test
                              Table "public.test"
 Column |       Type        |                     Modifiers
--------+-------------------+-------------------------------
 id     | integer           | not null default nextval('test_id_seq'::regclass)
 first  | integer           |
 last   | integer           |
 value  | character varying |

select * from test;
 id | first | last | value
----+-------+------+-------
  1 |     1 |    2 |
  4 |     3 |    5 |
  5 |     7 |   10 |
(3 rows)

Для простоты, можно предположить, что first - это время входа, а last - время выхода. т.о. (first,last) - интервал времени

хочется добавить некое ограничение, чтобы данные вида
insert into test (first, last) values(8, 11) НЕ принимались. т.е.
проверять уже введенные интервалы и новый на пересечение.

можно конечно все это реализовать на PHP но хочется более
симпатичного решения


Не сильно красивый, но рабочий варинант:

Делаем процедуру pl_update_test, которая обновляет таблицу по условию

CREATE FUNCTION "pl_update_test" (integer,integer) RETURNS smallint AS '
-- RETURNS 0 if updated, 1 if not updated
DECLARE
  result int2;
BEGIN
  SELECT INTO result id FROM test WHERE (SELECT max(last) FROM test)<$1;
  IF result IS NULL THEN
    INSERT INTO test (first, last) VALUES ($1, $2);
    RETURN 0;
  ELSE
    RETURN 1;
  END IF;
END;

' LANGUAGE 'plpgsql';

Затем вместо INSRT INTO... юзаем
SELECT pl_update_test (8, 11)

Если инсетнулось, то возвращает 0, если нет - 1

qqqq ★★
()
Ответ на: комментарий от qqqq

ПАРДОН. Там же пересечение. Переписал функцию. Предыдущий мессаг мона удалить. :)

Не сильно красивый, но рабочий варинант:

Делаем процедуру pl_update_test, которая обновляет таблицу по условию

CREATE FUNCTION "pl_update_test" (integer,integer) RETURNS smallint AS '
-- RETURNS 0 if updated, 1 if not updated
DECLARE
  result int2;
BEGIN
  SELECT INTO result COUNT(*)
         FROM (SELECT *, (first>$1 AND last<$2) OR
                         (first<$1 AND last>$2) OR
                         (first>$1 AND last>$2 AND first<$2) OR
                         (first<$1 AND last<$2 AND last>$1) as res FROM test) AS foo WHERE res=TRUE;
  IF result=0 THEN
    INSERT INTO test (first, last) VALUES ($1, $2);
    RETURN 0;
  ELSE
    RETURN 1;
  END IF;
END;
' LANGUAGE 'plpgsql';

Затем вместо INSRT INTO... юзаем
SELECT pl_update_test (8, 11)

Если инсетнулось, то возвращает 0, если нет &#8211; 1

qqqq ★★
()
Ответ на: комментарий от qqqq

Спасибо... в итоге что-подобное сам написал с той лишь разницей, что на функцию повесил триггер и юзаю INSERT INTO...

klon
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.