【问题标题】:MySQL INSERTing rows into a database with datetime sanity checksMySQL 使用日期时间完整性检查将行插入数据库
【发布时间】:2012-12-07 14:26:46
【问题描述】:

我正在制作一个会议室预订系统,在该系统中,开始和结束日期内不应该有任何时间,因此理论上验证应该在一个开始和结束日期时间范围内检查没有日期/时间。

我有两个表格,我可以将开始日期和结束日期都插入其中,所以我目前唯一感兴趣的列是这些

会议室
|------------------------------------|
|- 预订时间 -|-预订结束-|

我了解完整性检查背后的原理以及我可以在伪代码中进行的检查。这是我到目前为止的代码 - >

p4a_db::singleton()->query("INSERT INTO meetingrooms(location_id, bookingtime, bookingend, merono_id)
                WHERE bookingtime < " . $date . " AND bookingend > " . $date . "
                OR
                bookingdate < " . $date . " AND bookingend > " . $dateend . "
                VALUES(?,?,?,?)",
                array($location, $date, $dateend, $merono));

我不想将数据直接插入到语句中,但在我明白如何做到这一点之前,我被卡住了,所以这个问题,

我如何在插入数据之前执行完整性检查,这样我就不会在预定时间内得到日期。

任何帮助将不胜感激。

【问题讨论】:

  • 你不会先做一个查询吗? SELECT * FROM meetingrooms WHERE booking_start_time
  • 我不知道这就是为什么我问XD请解释一下?
  • 对不起。我太快按了“输入”。请参阅我的编辑。有用吗?
  • 你能不能给我一个答案,这样我就可以想象它了,(例如写一个示例代码)

标签: php mysql frameworks


【解决方案1】:

编辑:

我一直在想我的答案,我意识到旧的解决方案不适用于你的情况,因为你需要时间跨度,比较开始日期和结束日期是没有用的。

我的处理方式是:

  1. 将日期保存为 int,使用 24 小时制(早上 7:40 是 740,晚上 9:50 是 2150)
  2. 在以下位置检查存储的日期:(Start&lt;NewStart&lt;End)
  3. 在以下位置检查存储的日期:(Start&lt;NewEnd&lt;End)
  4. 处理多个房间时,只需将房间号+时间存储为int。这样你仍然可以使用 2 和 3 中的方法。

2 和 3 可以在 sql 查询中完成,请查看 this 链接。

旧答案(检查重复)

这是在插入文本之前如何检查重复项(在本例中为电子邮件)的示例:

    $emailexist = $mysqli->prepare("select email from users where email = ?");
    $emailexist->bind_param('s', $email);
    $emailexist->execute();
    $emailexist->store_result();
    if ($emailexist->num_rows > 0) {
        $emailexist->close();
        $mysqli->close();
        return true;
    }
    else {
        $emailexist->close();
        $mysqli->close();
        return false;
    }

它检查是否有包含该字符串的行。如果是这样(如果行数大于 0),则返回 true(这意味着日期已经存在)。

您可以根据自己的代码调整它。

但是,您也可以只将列设置为 UNIQUE。然后在尝试插入时出现错误。它更容易,并且您不会遇到并发连接问题。

【讨论】:

  • 将列设置为唯一的问题是我有几个会议室的列可能重叠,我完全忘记了,直到你提到:P 我想我知道怎么做对它进行排序,但直到我尝试才知道:P 哦,我使用的是 php 框架,所以大部分我需要解密才能开始工作,我会回复你 =]
  • 试试吧,有很多方法可以解决这个问题:)(例如存储房间号和时间的组合)
  • 它让 if else 方法工作我正在努力而不是其他任何事情(现在)hrm 我想知道我将如何获得结果的数量,我将查看文档,看看我是否什么都能找到。感谢您的帮助=]
  • 我想我知道你的意思,虽然通常你的任务是做我给你一些想法的想法,查看编辑的答案:) 下次一定要只问具体问题,而不是一个完整的过程。
【解决方案2】:

经过长时间的深入搜索,我现在得到了这个方法的一个工作示例,以及一个防止 sql 注入的方法,代码如下;

if ($this->BookingValue == 1)
    {
        $sql = "SELECT COUNT(*) as num FROM meeting_room_bookings
                WHERE
                (
                (? < start_at AND ? > start_at)
                OR
                (? > start_at AND ? < end_at)
                )
                AND
                meeting_room_id = ?";

        $result = p4a_db::singleton()->fetchRow($sql, array($date, $date, $date, $dateend, $merono));

        if ( 0 == $result["num"] )
        {

         p4a_db::singleton()->query("INSERT INTO meeting_room_bookings (start_at, end_at, meeting_room_id)
                    VALUES
                    (?,?,?)", array($date, $dateend, $merono));

            return true;
        }       
        else
        {
         return false;

这段代码没有太多解释,但就差异而言,(不包括与表中列名的变化)现在查询是在设置值之前准备好的,那么可以在if 语句,从而允许进行验证以过滤不同日期之间的结果。

除此之外,我还添加了验证,以通过 AND 语句将其他会议室的日期停止包含在语句中,其中会议室 ID 被限制为单个值。

虽然现在,这将导致一个单独的问题是来自该语句的另一个抛出的错误,我知道插入是正确的,但是这个准备好的语句中的某些东西会导致错误:

SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens File: Pdo.php, Line: 234

虽然现在我正在调查从准备好的语句中抛出的错误,并且会在有修复时更新此答案,但感谢您的帮助。

【讨论】:

    猜你喜欢
    • 2013-04-27
    • 2013-01-28
    • 2019-10-06
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多