Убедитесь, что строка Oracle представляет уникальный промежуток времени - PullRequest
0 голосов
/ 24 мая 2010

Я должен сделать процесс в Oracle / PLSQL. Я должен убедиться, что интервал времени между start_date и end_date из новой строки, которую я создаю, не должен пересекать другие start_date и end_dates из других строк.

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

Я не знаю, как делать повторяющиеся инструкции в Oracle / PLSQL, и я был бы признателен, если бы вы мне помогли.

Мне нужен такой цикл или что-то подобное, чтобы проверить каждую строку в моей таблице, что интервал времени, заданный date_hour_i и date_hour_e, не пересекает другие интервалы времени, заданные остальными строками. Еще одна спецификация .... даты из каждой строки соответствуют клиенту и сотруднику, который выполняет стрижку для клиента в заданный интервал времени .... и я хочу как-то не позволить ввести новую строку, если для тот же клиент (или другой клиент) и сотрудник, новый интервал времени пересекает другие интервалы времени с тем же / другим клиентом и сотрудником .... я надеюсь, что я дал понять ...

Ответы [ 4 ]

1 голос
/ 25 мая 2010

Две ссылки для вашего удовольствия от чтения: -

Временные интервалы без наложений

и

Избегание значений наложения ...

0 голосов
/ 24 мая 2010

Я предполагаю, что это будет во время триггера ПЕРЕД вставкой или обновлением.

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

Вы можете обойти это, используя PRAGMA AUTONOMOUS_TRANSACTION, чтобы создать новую тему.

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

CREATE OR REPLACE TRIGGER mytrigger
BEFORE INSERT OR UPDATE ON mytable FOR EACH ROW
DECLARE 
    cnt number;
BEGIN 
    SELECT count(*) into cnt
    FROM reserved_date_range                
    WHERE :new.begin_date BETWEEN begin_dt and end_dt

    if ( cnt > 0 ) then
        raise_application_error(-20000,'Overlapping date ranges');
    else
        insert into reserved_date_range( begin_dt, end_dt ) 
        values ( :new.begin_date, :new.end_date );
    end if;
End;
/
0 голосов
/ 25 мая 2010

Скажите, что ваша таблица - tab1, дата начала - stdate, а дата окончания - endate также пусть новая начальная дата и новая конечная дата будут в переменных PLSQL v_stdate и v_endate.

так что ваша вставка может быть что-то вроде

insert into tab1 (stdate,endate)
select v_stdate,v_endate  from dual
where not exists(
select 'overlap' from tab1 t1
where v_stdate between(t1.stdate and nvl(t1.endate,v_endate) 
or   v_endate between(t1.stdate and nvl(t1.endate,v_endate)

)

Решение этой проблемы немного сложнее из-за проблем параллелизма. В вашем случае вы планируете событие (или ресурс). Итак, я полагаю, у вас есть таблица, которая содержит ресурс (скажем, клиент). Прежде чем добавить другое расписание (или событие) для клиента, вы должны заблокировать конкретную запись клиента, например.

select client_id from Clients where client_id=p_client_id for update;

Затем вы можете проверить, нет ли перекрытий, вставить новое расписание и зафиксировать. На этом этапе блокировка будет снята. Любое решение, не использующее объект сериализации, обязательно будет иметь недостатки из-за проблем параллелизма. это в вашей PLSQL или в триггере после вставки. Но это абсолютно необходимо для блокировки фактической записи ресурса.

0 голосов
/ 24 мая 2010

зачем проверять каждый ряд?просто запросите время начала и окончания.если результат> 0, выведите сообщение об ошибке, иначе вставьте.

...