gpt4 book ai didi

php - SQLite在文本字段中未正确排序日期

转载 作者:行者123 更新时间:2023-12-03 18:32:29 26 4
gpt4 key购买 nike

我有一个PHP脚本,可以将一些日程表保存在sqlite数据库中。一直有效,直到近两周前我注意到sqlite的行为很奇怪。我将日期保存在文本字段中,无法按日期对记录进行排序。

例如,我有一些最近添加的2月日期,如果我运行查询以返回8月22日之后的日期:

SELECT `date`, hex(`date`), substr(`date`, 1, 1), substr(`date`, 1) 
FROM Schedules WHERE `date` > '2019-08-22' order by `date`


我得到了记录:

`date`              hex(`date`)                substr(`date`, 1, 1) substr(`date`, 1)
2019-08-22 13:00 323031392D30382D32322031333A3030 2 2019-08-22 13:00
2019-02-04 12:00 323031392D30322D30342031323A3030 2 2019-02-04 12:00
2019-02-18 12:00 323031392D30322D31382031323A3030 2 2019-02-18 12:00
2019-03-04 12:00 323031392D30332D30342031323A3030 2 2019-03-04 12:00


第一条记录是正确的,我将其包括在内以与错误的记录进行比较。我考虑过在实际数字之前添加一些字符,但从十六进制列来看似乎并非如此。我什至试图请求大于“ 3000”的日期来排除破折号(也许他们有一些Unicode字符),并且它会继续返回先前结果的最后三个记录。

该表定义为:

CREATE TABLE `Schedules` (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`date` TEXT
);


我添加记录的php代码是:

class Schedule {
public static function add_schedule($programmed_date, $programmed_time, $options) {
$result = 0;
date_default_timezone_set('Europe/Rome');
$date = DateTime::createFromFormat('d/m/Y H:i', "$programmed_date $programmed_time");
$now = new DateTime();
if ($date < $now)
return -1;
$dbh = self::connect_to_database();
$stmt = $dbh->prepare('INSERT INTO Schedules(`date`) VALUES (:date)');
$stmt->bindValue(':date', $date->format('Y-m-d H:i'), SQLITE3_TEXT);
try {
$execution = $stmt->execute();
if ($execution !== FALSE)
$result = 1;
}
catch (Exception $ex) {}
finally {
$stmt->closeCursor();
}
$dbh = null;
return $result;
}

private static function connect_to_database() {
$db_path = Credentials::read_info('schedule')['db_path'];
try {
$dbh = new PDO('sqlite:'.$db_path);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo 'Connection failed: '.$e->getMessage();
exit;
}
return $dbh;
}
}


在这一点上,我无法猜测代码出了什么问题。 sql语句应仅返回第一条记录,而不是四条。有什么想法吗?谢谢。

SQLite DateTime comparison引导我进入 https://www.sqlite.org/lang_datefunc.html,如果运行查询,我找到了一种解决方法:

SELECT `date`, hex(`date`), substr(`date`, 1, 1), substr(`date`, 1) 
FROM Schedules WHERE datetime(`date`) > datetime('2019-08-22') order by `date`


它可以正常工作,只返回8月22日的记录。但是,我一直想知道为什么在 https://www.db-fiddle.com/f/ar9JxpaCo2wcQB1MobyaVv/0中存在转储时,纯文本比较和顺序搞乱了结果,并且您清楚地看到了我在此处编写的第一个查询返回了不同的(正确的)结果。
如果要直接尝试到我的数据库,可以从 here下载

最佳答案

好吧,那很有趣。我下载了数据库,并在数据库浏览器中播放了sqlite(只读),直到发现一些有趣的东西。它以胖手指date > '21'开头(找到了3个较早的日期)。最后,这个sql select *,typeof(date) from Schedules揭示了一些东西

349|2019-08-22 13:00|text
374|2019-02-04 12:00|blob
375|2019-02-18 12:00|blob
376|2019-03-04 12:00|blob


我创建了一个repro,发现如果从 SQLITE3_TEXT中删除​​ bindValue,它将以文本形式插入日期。

关于php - SQLite在文本字段中未正确排序日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54328545/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com