无法从具有日期时间格式的 col 获取数据
Posted
技术标签:
【中文标题】无法从具有日期时间格式的 col 获取数据【英文标题】:Can't get data from col which has datetime format 【发布时间】:2020-05-30 11:56:28 【问题描述】:我正在尝试从 MS SQL Server 获取按当前时间过滤的列数据。单元格具有datetime
格式。但我得到空洞的回应。哪里出错了?
<?php
$serverName = ''; // server name
$cinfo = array(
"Database" => "", // database
"UID" => "", // user
"PWD" => "" // pass
);
$conn = sqlsrv_connect($serverName, $cinfo);
if ($conn)
echo "connected" . "<br/>";
$datetimenow = current_time("d.m.Y H:i"); // wordpress function
echo $datetimenow . "<br/>"; // 30.05.2020 14:10
if (($result = sqlsrv_query($conn, "SELECT * FROM dbo.GorElectroTrans WHERE GPS_datetime=$datetimenow")) !== false)
while ($obj = sqlsrv_fetch_object($result))
echo $obj->Longitude . '<br />';
else
die(print_r(sqlsrv_errors(), true));
?>
【问题讨论】:
您是否需要在=$datetimenow"
中的插入值周围加上某种形式的引号,最好还是使用准备好的语句。
@NigelRen 对不起,我是 PHP 新手,如何正确?
尝试使用参数化查询,也就是Prepared Statements。您不仅可以避免处理引用数据,还可以帮助您避免Little Bobby Tables 的问题。
@AlwaysLearning 有 mysql 示例,它可以与 MS SQL 一起使用吗?
你试过了吗,管理工作室,SELECT * FROM dbo.GorElectroTrans WHERE GPS_datetime= <'datetimeNow'>
。这里,<'datetimeNow'>
是您从 php 传递的值。
【参考方案1】:
您需要更改语句并使用参数化查询来防止可能的 SQL 注入问题。正如documentation 中提到的,sqlsrv_query 函数非常适合一次性查询,除非有特殊情况,否则应该是执行查询的默认选择。此函数提供了一种简化的方法,可以用最少的代码执行查询。 sqlsrv_query函数既做语句准备也做语句执行,可以用来执行参数化查询。
当您为datetime
值使用参数时,您有两种选择:
datetime
值作为文本传递,对$datetimenow
变量的值使用明确的datetime
格式(在您的情况下,函数current_time
将当前时间作为文本从格式化的PHP 日期时间对象返回)。
使用扩展参数语法将 datetime
值作为 PHP 日期时间对象传递。
PHP:
<?php
$serverName = ''; // server name
$cinfo = array(
"Database" => "", // database
"UID" => "", // user
"PWD" => "" // pass
);
$conn = sqlsrv_connect($serverName, $cinfo);
if ($conn)
echo "connected" . "<br/>";
// Datetime value in `yyyy-mm-ddThh:mi:ss` format
$datetimenow = current_time("Y-m-d\TH:i:00");
// or if you want a specific datetime value
//$datetimenow = '2020-05-30T14:10:00';
// Pass datetime value as text
$sql = "SELECT * FROM dbo.GorElectroTrans WHERE GPS_datetime = ?";
$params = array($datetimenow);
if (($result = sqlsrv_query($conn, $sql, $params)) !== false)
while ($obj = sqlsrv_fetch_object($result))
echo $obj->Longitude . '<br />';
// Pass datetime value as PHP datetime object
$sql = "SELECT * FROM dbo.GorElectroTrans WHERE GPS_datetime = ?";
$params = array(
array(
date_create_from_format('Y-m-d\TH:i:s', $datetimenow),
SQLSRV_PARAM_IN,
SQLSRV_PHPTYPE_DATETIME,
SQLSRV_SQLTYPE_DATETIME
)
);
if (($result = sqlsrv_query($conn, $sql, $params)) !== false)
while ($obj = sqlsrv_fetch_object($result))
echo $obj->Longitude . '<br />';
else
die(print_r(sqlsrv_errors(), true));
?>
补充说明:
当您从 SQL Server 中检索数据时,datetime
的值默认为returned 作为 PHP 的 datetime
对象,因此您需要使用 DateTime->format()
或在连接字符串中设置 'ReturnDatesAsStrings'
选项或在语句级别。
当您将绑定值发送到十进制或数字列(documentation 中也提到)时,建议使用字符串作为输入以确保精度和准确性,因为 PHP 对浮点数的精度有限。这同样适用于 bigint 列,尤其是当值超出整数范围时。
【讨论】:
为什么在这种情况下不起作用:$date1 = '2020-05-30T22:03:00'; $date2 = '2020-05-30T22:05:00'; $sql = "SELECT * FROM dbo.GorElectroTrans WHERE GPS_datetime >= ? AND <= ?"; $params = array($date1, $date2);
表格截图imgur.com/a/G8OIB2C
WHERE
子句是错误的。您需要使用"SELECT * FROM dbo.GorElectroTrans WHERE GPS_datetime >= ? AND GPS_datetime <= ?"
或WHERE GPS_datetime BETWEEN ? AND ?
。
哦,谢谢!还有一个问题:例如,当我尝试在 2020-05-30T22:03:00 获取行时,我得到空响应,我认为它与秒相关。在原始表格中,我看不到秒,在这种情况下我应该怎么做?
@EugeneChefranov 好吧,你可以试试这样的东西:$date1 = '2020-05-30T22:03:00'; $date2 = '2020-05-30T22:04:00'; $sql = "SELECT * FROM dbo.GorElectroTrans WHERE ? <= GPS_datetime AND GPS_datetime < ?"; $params = array($date1, $date2);
。
是的,我也考虑过这种情况,但表格显示了目前城市的公共交通位置,表格每 1-2 秒更新一次。我想我需要像这样$date1 = '2020-05-30T22:03:00'; $date2 = '2020-05-30T22:03:03';
每 2-3 秒获取一次表格以上是关于无法从具有日期时间格式的 col 获取数据的主要内容,如果未能解决你的问题,请参考以下文章
从 JSpinner 获取日期并放入具有 DATE 格式的 MySQL 数据库列
无法获取引导日期时间选择器以在表单字段中显示格式化的数据库值