我有一个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
下载答案 0 :(得分:2)
嗯,那很有趣。我下载了数据库,并在数据库浏览器中播放了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
我创建了一个复制子,如果从SQLITE3_TEXT
中删除了bindValue
,它将把日期插入为文本。
答案 1 :(得分:1)
在@DinoCoderSaurus中回答,您有理由说明您的数据表现不正常。
我发现的解决方法是:
margin: auto
这样,您将获得预期的结果。
空字符串串联会将.special-background .row > div {
height: 100%;
}
.img-fluid {
max-heihgt: 100%;
width: auto;
margin: auto;
}
转换回WHERE date || '' > '2019-08-22'
。