SQL,在计算两次之间的差异时插入表
Posted
技术标签:
【中文标题】SQL,在计算两次之间的差异时插入表【英文标题】:SQL, insert into table while calculating difference between two times 【发布时间】:2020-01-23 09:54:22 【问题描述】:我目前正在使用 fullcalendar 制作一个简单的日历。我的数据库有三个日期时间:
start
end
total
我想要的是程序,因为它插入日期,以计算开始和结束之间的差异并将其添加到总数中。这是我的插入 SQL 代码:
我在 mysql 中使用 InnoDB。
session_start();
include_once './conexao.php';
$dados = filter_input_array(INPUT_POST, FILTER_DEFAULT);
//Converter a data e hora do formato brasileiro para o formato do Banco de Dados
$data_start = str_replace('/', '-', $dados['start']);
$data_start_conv = date("Y-m-d H:i:s", strtotime($data_start));
$data_end = str_replace('/', '-', $dados['end']);
$data_end_conv = date("Y-m-d H:i:s", strtotime($data_end));
$query_event = "INSERT INTO events (title, name, color, start, end, total) "
. "VALUES (:title, :name, :color, :start, :end) "
. "SELECT DATEDIFF(':start', ':end') AS total";
$insert_event = $conn->prepare($query_event);
$insert_event->bindParam(':title', $dados['title']);
$insert_event->bindParam(':name', $dados['name']);
$insert_event->bindParam(':color', $dados['color']);
$insert_event->bindParam(':start', $data_start_conv);
$insert_event->bindParam(':end', $data_end_conv);
if ($insert_event->execute())
$retorna = ['sit' => true, 'msg' => '<div class="alert alert-success" role="alert">Evento inserido com sucesso!</div>'];
$_SESSION['msg'] = '<div class="alert alert-success" role="alert">Evento inserido com sucesso!</div>';
else
$retorna = ['sit' => false, 'msg' => '<div class="alert alert-danger" role="alert">Erro: Evento não foi inserido com sucesso!</div>'];
header('Content-Type: application/json');
echo json_encode($retorna);```
【问题讨论】:
运行这段代码会发生什么?你有错误吗? 【参考方案1】:我可以看到您一定遇到了 SQL 语法错误 - 您不能在同一个查询中使用 INSERT...VALUES
和 INSERT...SELECT
语法 - 您必须使用其中一个。但是这里不需要SELECT
,您可以将 DATEDIFF 函数作为值之一。传递给 DATEDIFF 的参数也不需要引号。
您也不能在 PDO 中使用相同的参数名称两次。
我认为这应该会更好(虽然我无法测试它,显然):
$query_event = "INSERT INTO events (title, name, color, start, end, total) "
. "VALUES (:title, :name, :color, :start, :end, DATEDIFF(:start2, :end2))";
$insert_event = $conn->prepare($query_event);
$insert_event->bindParam(':title', $dados['title']);
$insert_event->bindParam(':name', $dados['name']);
$insert_event->bindParam(':color', $dados['color']);
$insert_event->bindParam(':start', $data_start_conv);
$insert_event->bindParam(':end', $data_end_conv);
$insert_event->bindParam(':start2', $data_start_conv);
$insert_event->bindParam(':end2', $data_end_conv);
附:如果你在运行代码时还有其他问题,你需要具体解释一下,因为你一开始没有提到。
【讨论】:
我无法使用此代码插入任何内容,并且我没有收到任何错误。它可能与我管理日历的 JS 脚本有关。此代码:pastebin.com/pCawrQQP 能够插入数据,是我在尝试计算差异之前所做的代码 如果你认为错误在JS端,你需要调试JS端,检查是否甚至触发了PHP执行。你没有显示任何这些,所以我无法帮助你。但是这个答案应该可以解决 PHP 的问题。也许您应该使用 PostMan 之类的工具对 PHP 部分进行单元测试以生成 HTTP 请求,然后一旦它工作正常,您就可以修复客户端代码以使其正确生成自己的请求。 @Rui 如果你认为这个查询仍然有错误,那么你需要调试它。确保 PDO 设置为在发生错误时抛出异常(请参阅php.net/manual/en/pdo.error-handling.php)并确保 PHP 设置为记录和/或回显错误(请参阅stackify.com/php-error-logs-guide)。设置它,然后再次运行代码,看看它报告了什么。这样你可能对如何开始修复它有一个更好的想法。 P.S.无论如何,我不相信你真的需要这个total
专栏。可以使用您已经存储的“开始”和“结束”值随时计算这样的值。关系数据库理论通常建议您不要存储可以使用其他存储值计算的值 - 相反,您只需在 SELECT 查询中按需执行计算,只要您想查看该数据。 (唯一的例外是计算运行速度很慢,尤其是对于大型数据集。但这不应该是一个大问题。)
感谢这里给我的时间,我肯定会设置错误处理,因为我确实忘记这样做了。我还将进一步研究 SELECT 查询,看看是否可以使用 html 表进行计算【参考方案2】:
不要在一个插入语句中混合使用 Values 子句和 Select 子句。 你有两种选择:
$query_event = "INSERT INTO events (title, name, color, start, end, total) "
. "VALUES (:title, :name, :color, :start, :end, DATEDIFF(':start', ':end')) "
$query_event = "INSERT INTO events (title, name, color, start, end, total) "
. "SELECT :title, :name, :color, :start, :end, DATEDIFF(':start', ':end') AS total from dual";
【讨论】:
您好,感谢您的代码。我使用了第二个,它可以插入,但是当类型设置为 int 或空字符串时,它会将总计打印为 0。这可能与我的日期格式有关?设置如下:YYYY-MM-DD HH:MM:SS Datediff 给出天数。这可以是 0。您还可以使用 timediff,它以小时为单位给出开始和结束之间的时间 没错,但是假设 start = 2020-02-10 和 end = 2020-02-15,时间差应该是 5 或 -5,具体取决于您如何设置代码。这对我来说不是这种情况,无论两个日期之间的长度差异如何,由于某种原因,结果总是为 0。我会进一步调查,谢谢你的时间!【参考方案3】:[编辑] 我认为这可以做到:
INSERT INTO events (title, name, color, start, end, total)
SELECT :title, :name, :color, t.start, t.end, DATEDIFF(t.start, t.end) )
FROM ( SELECT :start, :end) AS t
但您需要尝试确定。
【讨论】:
您不能在 PDO 中两次使用相同的参数名称...另外,您不打算解释一下为什么您的版本更好吗?这将是一个更有用的答案。 @ADyson 啊sh*,最近PL做的太多了,完全忘记了,谢谢。 @ADyson 比 ?操作请求?它应该工作;您的答案 ?我不认为它更好,只是不同;)我在 SQL 端放了更多逻辑,你把它放在 PHP 上:并没有太大的区别。 (而且我没有看到任何真正有用的大答案) 比 OP 的代码更好 - 即解释您所做的更改以及为什么它可以解决问题。代码转储本身对那些一开始不理解他们的错误的人没有用......我在评论你的原始版本,不要忘记,而不是你改变的 SQL。您的代码是否比我的“更好”由 OP 决定,而不是我。我说的是你帖子的整体质量。我试图通过添加一些解释性说明来鼓励您使其更有用 - 这并不是为了对其本身进行简单的批评。 感谢@Blag 的评论,这段代码和Adyson 有同样的问题,可能与我设置JS 代码的方式有关,我会进一步研究。以上是关于SQL,在计算两次之间的差异时插入表的主要内容,如果未能解决你的问题,请参考以下文章