2010-05-24 3 views
0

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

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

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

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

+0

На самом деле, это * это * вопрос. Просто опубликуйте структуру таблицы, о которой вы говорите. – eKek0

+0

Oracle PL/SQL - это расширение SQL, язык структурированных запросов. Постарайтесь думать в терминах заданных операций вместо процедурных шагов. Вместо «проверки каждой строки» вам нужно запросить любые строки, соответствующие определенному условию. –

ответ

0

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

0

Я предполагаю, что это будет во время триггера ДО ВСТАВКИ ИЛИ ОБНОВЛЕНИЯ.

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

Вы можете обойти это, используя 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

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

+1

Снова проблемы параллелизма могут испортить это решение. Что если другая вставка (скажем, другого пользователя) происходит между операторами select и insert и что вставка имеет перекрытие. Тогда все наши решения, которые сканируют таблицу для перекрытий, потерпят неудачу. – josephj1989

+0

У триггера выше НЕ будет проблемы параллелизма - потому что это происходит в триггере. СУРБД будет иметь последовательное представление запроса вождения, а вставки будут выполняться последовательно. – Randy

0

Скажите ваш стол tab1 и дата начала - stdate, а дата окончания - , а также новая дата начала и новая дата окончания в переменных 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; 

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

 Смежные вопросы

  • Нет связанных вопросов^_^