如何更新数据库中的日期间隔(Hibernate HQL)

时间:2017-06-08 16:25:42

标签: mysql sql sql-server hibernate hql

对于标识为id的特定数据库条目,请考虑数据库中的日期间隔,从BEGIN_DATEEND_DATE,表示为(BEGIN_DATE,{{ 1}})。

鉴于两个新日期构成了区间(END_DATEnewBeginDate),我必须更新(newEndDateBEGIN_DATE),以便生成的区间包含全部4日期。换句话说,我想添加两个区间(因为我添加它们,结果区间可能保持不变或增长,但从不收缩)。

举几个例子:

如果(END_DATEBEGIN_DATE)=(END_DATEJanuary 10),则:

  • January 20BEGIN_DATE)+(END_DATEJan 15)=(Jan 25Jan 10

  • Jan 25BEGIN_DATE)+(END_DATEJan 05)=(Jan 15Jan 05

  • Jan 20BEGIN_DATE)+(END_DATEJan 05)=(Jan 25Jan 05

  • Jan 25BEGIN_DATE)+(END_DATEJan 15)=(Jan 15Jan 10

  • Jan 20BEGIN_DATE)+(END_DATEJan 10)=(Jan 13Jan 10

以下两个查询共同实现了这一目标。第一个更新Jan 20,第二个更新BEGIN_DATE

END_DATE

我的问题是: 如何在单个查询中执行此操作?

2 个答案:

答案 0 :(得分:1)

当涉及到更复杂的编程结构时,SQL是有限的,所以既然你使用Hibernate我就会读取约会实体实例并更新它的字段。这将需要两个查询,一个用于读取,一个用于更新,但它仍然只是一个更新语句,并且是最易读的解决方案。

如果您仍然只需要一个更新语句而不需要其他任何内容,则可以使用case将您的两个语句合并为一个:

update APPOINTMENTS 
set BEGIN_DATE = case when (BEGIN_DATE is null or BEGIN_DATE > :newBeginDate) then :newBeginDate else BEGIN_DATE end,
    END_DATE = case when (END_DATE is null or END_DATE < :newEndDate) then :newEndDate else END_DATE end
where (BEGIN_DATE is null or BEGIN_DATE > :newBeginDate or END_DATE is null or END_DATE < :newEndDate)
    and ID = :id

答案 1 :(得分:1)

使用LEAST()GREATEST()功能。对于NULL,请使用COALESCE()

update APPOINTMENTS
set BEGIN_DATE = coalesce(least(BEGIN_DATE, :newBeginDate), :newBeginDate),
    END_DATE   = coalesce(greatest(END_DATE, :newEndDate), :newEndDate)
where ID = :id

我认为最不可能并不需要解释。如果旧日期为NULL,COALESCE将选择新日期。因此,在WHERE子句中不需要除ID = :id之外的任何条件。