У меня есть php-скрипт, который сохраняет в базе данных sqlite некоторые расписания.Это всегда работало, пока я не заметил почти две недели назад, что у sqlite было странное поведение.Я сохраняю даты в текстовом поле, и записи не могут быть упорядочены по дате.
Например, у меня есть несколько недавно добавленных дат для февраля, и если я выполню запрос, чтобы вернуть даты после 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, чтобы исключить дефис (возможно, у них был какой-то символ в юникоде), и он продолжал возвращать последние три записи предыдущих результатов.
Таблица определяется как:
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 привело меня к 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`
Это работаетправильно вернул только запись за 22 августа.Однако я продолжаю задаваться вопросом, почему сравнение и порядок в обычном тексте приводят к ошибкам, когда здесь https://www.db -fiddle.com / f / ar9JxpaCo2wcQB1MobyaVv / 0 есть дамп, и вы ясно видите, что первый запрос, который я написалздесь возвращает другой (и правильный) результат.Если вы хотите попробовать напрямую в мою базу данных, вы можете скачать ее с здесь