确保 Oracle 行代表唯一的时间跨度

发布于 2024-09-02 13:48:40 字数 443 浏览 1 评论 0原文

我必须在 Oracle/PLSQL 中创建一个过程。我必须验证我创建的新行中的 start_date 和 end_date 之间的时间间隔不得与其他行中的其他 start_dates 和 end_dates 相交。

现在我需要检查每一行是否存在该条件,如果不对应,则重复指令应停止,然后显示一条消息,例如“给定的时间间隔不正确”。

我不知道如何在 Oracle/PLSQL 中进行重复指令,如果您能帮助我,我将不胜感激。

我需要一个循环或类似的东西来验证表中的每一行,date_hour_i 和 date_hour_e 给出的时间间隔不与其余行给出的其他时间间隔相交。还有一个规范......每一行的日期对应于一个客户和一个在给定时间间隔内为客户理发的员工......并且我想以某种方式不让引入新行,如果同一客户(或其他客户)和员工,新的时间间隔与同一/其他客户和员工的其他时间间隔相交......我希望我说清楚......

I have to make a process in Oracle/PLSQL. I have to verify that the interval of time between start_date and end_date from a new row that I create must not intersect other start_dates and end_dates from other rows.

Now I need to check each row for that condition and if it doesn't correspond the repetitive instruction should stop and after that to display a message such as "The interval of time given is not correct".

I don't know how to make repetitive instructions in Oracle/PLSQL and I would appreciate if you would help me.

I need a loop or smth like that to verify each row in my table that the interval of time given by the date_hour_i and date_hour_e does not intersect the other intervals of time given by the rest of the rows. One more specification....the dates from each row correspond to a client and a employee that performs a haircut to the client in the given interval of time....and i want somehow not to let to introduce a new row if for the same client(or other client) and employee, the new interval of time intersects the other intervals of time with the same/other client and employee....i hope i made myself clear...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

杀手六號 2024-09-09 13:48:40

两个链接供您阅读乐趣:-

没有重叠的时间间隔

避免重叠值...

Two links for your reading pleasure:-

Time intervals with no overlaps

and

Avoiding overlap values...

烧了回忆取暖 2024-09-09 13:48:40

为什么要检查每一行?只需查询开始和结束时间。如果结果> 0,输出错误信息,否则插入。

why check each row? just query for the start and end times. if the result > 0, output the error message, else, insert.

森林迷了鹿 2024-09-09 13:48:40

我假设这将是在 BEFORE INSERT OR UPDATE 触发器期间。

您将需要查询现有表中的日期重叠 - 但这会产生突变触发器错误。

您可以通过使用 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;
/

i assume this will be during the BEFORE INSERT OR UPDATE trigger.

you will want to query the existing table for overlaps in the dates - but this will give a mutating trigger error.

You can get around this by using PRAGMA AUTONOMOUS_TRANSACTION to spawn a new thread.

alternately - you could save each date range in a secondary table, and use that to query against on each insert... something like the following (uncompiled)

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;
/
幻梦 2024-09-09 13:48:40

假设您的表是 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 或插入后触发器中。但绝对必须锁定实际资源记录。

Say your table is tab1 and the start date is stdate and end date is endate
also let new start date and new end date be in PLSQL variables v_stdate and v_endate.

so your insert can be something like

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)

)

The solution to this problem is a bit complicated because of concurrency issues. In your case you are scheduling an event (or a resource).So I suppose you have a table that holds resource (say client). Before you add another schedule (or event) for a client you should lock the particular client record like.

select client_id from Clients where client_id=p_client_id for update;

Then you can verify there are no overlaps and insert the new schedule and commit.At this point the lock will be released.Any solution that does not use a serialization object is bound to be flawed due to concurrency issues.You can do it in your PLSQL or in a After Insert trigger.But it is an absolute must to lock the actual resource record.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文