我正在开展项目,我必须在同一天阻止时间重叠。用户必须选择选择日期,投递日期,选择时间和投放时间。我的逻辑工作正常,可以防止时间重叠,但我试图弄清楚如何让用户选择相同的日期,然后比较时间。这是我的HTML代码:
<tr>
<td>
<label>Pick up Date</label>
<input name="DateFrom" id="DateFrom" type="text" size="10" maxlength="10" value="">
<label>Pick up Time</label>
<input name="TimeFrom" id="TimeFrom" type="text" size="10" maxlength="10" value="">
</td>
</tr>
<tr>
<td>
<label>Drop off Date</label>
<input name="DateTo" id="DateTo" type="text" size="10" maxlength="10" value="">
<label>Drop off Time</label>
<input name="TimeTo" id="TimeTo" type="text" size="10" maxlength="10" value="">
</td>
</tr>
这是我传递参数的逻辑:
<cfargument name="DateFrom" type="string" required="yes">
<cfargument name="DateTo" type="string" required="yes">
<cfargument name="TimeFrom" type="string" required="yes">
<cfargument name="TimeTo" type="string" required="yes">
<cfquery name="qryTest">
Select PickDate,DropDate,PickTime,DropTime
From ptReservation
Order by PickDate
</cfquery>
<cfif (arguments.TimeTo LT qryTest.PickTime OR qryTest.DropTime LT arguments.TimeFrom)>
<cfquery name="addReservation" datasource="testData">
//Do insert
</cfquery>
</cfif>
因此,例如我的代码会阻止和时间重叠,但如果时间不在同一天,该怎么办呢。我如何首先检查日期是否匹配,然后检查时间重叠?如果有人可以帮忙解决这个问题,请告诉我。
答案 0 :(得分:2)
坦率地说,将日期和时间存储在不同的列中会使这项任务比IMO更难。在预订系统中,两者是整体相关的。将它们分开只会使执行常见任务变得更加困难,例如检查冲突或重叠(由最近的线程支持)。除非有充分的理由将它们分开,否则我建议重组表并将预订日期和时间存储在单列中。
例如,使用这样的结构,您可以轻松检查单个查询中的冲突预留,即使是跨越多天的预留:
添加新记录时,只有在未找到冲突的预留时才使用EXISTS
子句插入记录:
<!--- example of reservation date/time to check --->
<cfset requestedStartDateTime = createDateTime(2016, 1, 14, 14, 0, 0)>
<cfset requestedEndDateTime = createDateTime(2016, 1, 15, 16, 0, 0)>
...
<cfquery result="yourResult" ....>
INSERT INTO Reservation ( startDateTime, endDateTime, .... )
SELECT <cfqueryparam value="#requestedStartDateTime#" cfsqltype="cf_sql_timestamp">
, <cfqueryparam value="#requestedEndDateTime#" cfsqltype="cf_sql_timestamp">
, ....
WHERE NOT EXISTS
(
<!--- existing reservation that would overlap --->
SELECT reservationID
FROM reservation
WHERE startDateTime < <cfqueryparam value="#requestedEndDateTime#" cfsqltype="cf_sql_timestamp">
AND endDateTime > <cfqueryparam value="#requestedStartDateTime#" cfsqltype="cf_sql_timestamp">
)
</cfquery>
您可以通过检查cfquery的result
属性来确定结果。如果result.recordcount
是&gt; 0,插入新预订。否则,您知道发现了冲突并可以采取相应措施。使用CF9 / 11和MySQL5.6进行测试。
<cfif yourResult.recordCount gt 0>
SUCCESS: New reservation added
<cfelse>
ERROR: Conflict detected. INSERT failed.
</cfif>
更新:如果您的表包含某种自动递增列,则另一个选项是使用返回的新ID值as part of the "result" structure。如果存在,则插入成功。否则,它失败了。请注意,在CF9等旧版本中,ID键名称是特定于数据库的,即MySQL - "generated_key"
。从CF10 +开始,您可以使用通用密钥名称generatedKey
。
<!--- ID was generated --->
<cfif structKeyExists(yourResult, "generated_key")>
SUCCESS: New reservation added
<cfelse>
ERROR: Conflict detected. INSERT failed.
</cfif>
如果您绝对无法更改表结构,另一种可能性是创建一个VIEW或COMPUTED COLUMN(如果您的数据库支持它),其中包含单个列中的组合日期和时间。这至少可以简化查询这两个值,并允许您使用上述技术来解决您的问题。但是,虽然它会简化SQL,但它们并不总是SARGable。因此,对于大型数据集,它们的性能可能不如单个索引列。