我有以下表结构:
表名:available
id (autoincremetn) | acc_id | start_date | end_date
-------------------------------------------------------
1 | 175 | 2015-05-26 | 2015-05-31 |
-------------------------------------------------------
2 | 175 | 2015-07-01 | 2015-07-07 |
-------------------------------------------------------
它用于定义日期范围可用性,例如。对于给定的 acc_id,start_date 和 end_date 之间的所有日期均不可用。
根据用户输入,我正在关闭不同的范围,但如果用户尝试关闭(提交)一个范围,该范围的开始日期或结束日期位于已存在的范围内(对于提交的 acc_id),我想抛出错误在数据库中。
在此示例中,start_date:2015-05-30 end_date:2015-06-04 将是一个很好的失败候选者。
我发现了这个质量检查:MySQL 重叠日期,无冲突 https://stackoverflow.com/questions/6519424/mysql-overlapping-dates-none-conflicting
这几乎解释了如何通过 2 个步骤、2 个查询以及中间的一些 PHP 逻辑来完成此操作。
但我想知道是否可以在一个插入语句中完成。
我最终会检查受影响的行是否成功或失败(子问题:除了日期重叠之外,是否有更方便的方法来检查它是否因其他原因而失败?)
EDIT:
为了回应 Petr 的评论,我将进一步指定验证:
应避免任何形式的重叠,即使是包含
整个范围或发现自己位于现有范围内。另外,如果
开始或结束日期必须等于现有的开始或结束日期
被认为是重叠。有时某些 acc_id 已经有更多
比表中的一个响亮,所以验证应该针对
具有给定 acc_id 的所有条目。
遗憾的是,仅使用 MySQL 这是不可能的。或者至少,实际上是这样。首选方法是使用 SQL CHECK 约束,这些约束位于 SQL 语言标准中。然而,MySQL 不支持它们。
See: https://dev.mysql.com/doc/refman/5.7/en/create-table.html https://dev.mysql.com/doc/refman/5.7/en/create-table.html
CHECK 子句被所有存储引擎解析但忽略。
似乎 PostgreSQL 确实支持表上的 CHECK 约束,但我不确定切换数据库引擎是否可行,或者是否值得为使用该功能而烦恼。
在 MySQL 中,可以使用触发器来解决这个问题,它会在插入/更新发生之前检查重叠行,并使用SIGNAL
陈述。 (看:https://dev.mysql.com/doc/refman/5.7/en/signal.html https://dev.mysql.com/doc/refman/5.7/en/signal.html)但是,要使用此解决方案,您必须使用最新的 MySQL 版本。
除了纯 SQL 解决方案之外,这通常是在应用程序逻辑中完成的,因此无论哪个程序访问 MySQL 数据库,通常都会通过请求新条目违反的每一行来检查此类约束。SELECT COUNT(id) ...
陈述。如果返回的计数大于 0,则不会进行插入/更新。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)