Symfony SQL иногда не дает результатов

У меня есть sql, который должен дать мне список, но иногда результат будет пустым. Это происходит случайно. Нет никаких изменений в пользователе, версии или чем-то еще. Просто еще один запрос, который иногда будет пустым.

Существует таблица базы данных, в которой есть триггер для сохранения значений. Если вставляется новая строка, то в таблице истории создается новая строка. Для новой таблицы есть столбцы «validFrom», для которых будет установлено значение sysdate. При обновлении старая строка будет установлена ​​с «validUntil», и будет вставлена ​​новая строка. Эта таблица имеет индекс SUB_ID.

Таблица не является материализованным представлением или представлением. Просто обычный стол.

SQL

SELECT h.ID, h.SUB_ID
FROM history h
WHERE 1=1
AND h.SUB_ID = :subId
                    AND (
                        1=1
                        AND ( 
                            TO_DATE(:startDate, 'YYYY-MM-DD HH24:MI:SS') >= h.VALIDFROM
                            AND TO_DATE(:startDate, 'YYYY-MM-DD HH24:MI:SS') <= NVL(h.VALIDUNTIL,sysdate)
                        ) OR ( 
                            TO_DATE(:startDate, 'YYYY-MM-DD HH24:MI:SS') <= h.VALIDFROM
                            AND TO_DATE(:endDate, 'YYYY-MM-DD HH24:MI:SS') >= NVL(h.VALIDUNTIL,sysdate)
                        ) OR ( 
                            TO_DATE(:endDate, 'YYYY-MM-DD HH24:MI:SS') >= h.VALIDFROM
                            AND TO_DATE(:endDate, 'YYYY-MM-DD HH24:MI:SS') <= NVL(h.VALIDUNTIL,sysdate)
                        )
                    )

PHP

$validFrom = new Datetime();
$validUntil = new Datetime();
$query = $this->db->prepare($query);
$query->bindValue('subId', 20180101123456789, PDO::PARAM_STR);
$query->bindValue('startDate', $validFrom->format('Y-m-d H:i:s'), PDO::PARAM_STR);
$query->bindValue('endDate', $validUntil->format('Y-m-d H:i:s'), PDO::PARAM_STR);
$query->execute();
$result = $query->fetchAll();

$result иногда будет пустым, а иногда будут результаты. Мой единственный обходной путь - попробовать до 500 раз, тогда я получу результат. Я тоже пробовал со сном (1), но он все еще случайный, когда результат будет нулевым. Только сценарий займет намного больше времени.

Если я попробую блок plsql с 500 попытками, то я получу 500-кратный результат.

Кто-то знает, почему это происходит?

Вы проверили, что $query не равен нулю ?? может быть, вы пропустили подключение к базе данных

Gar 28.05.2019 16:42

Итак, вы пытаетесь найти результаты с startDate и endDate как == текущее время?

Arleigh Hix 28.05.2019 20:40

@Gar Запрос не пустой. Всегда заполнял, но ничего не возвращалось. Код не изменился, просто запустите несколько раз. иногда есть результат, иногда нет.

DasBen 29.05.2019 09:25

@ArleighHix не совсем startDate и endDate являются границами. Могут быть действительные результаты, которые начинаются раньше, но действительны в промежутке, тогда есть те, которые только между, и те, которые начинаются между и заканчиваются после. Выбор даты работает для многих других таблиц, только эта иногда не выдает результатов

DasBen 29.05.2019 09:26
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
4
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После многих часов тестирования различных сценариев я нашел причину. Это вызвано тем, что sysdate оракула может быть старше, чем php datetime.

Можно было бы ожидать:

php new Datetime()->format('Y-m-d H:i:s') = 2019-06-05 12:55:00
oracle to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') >= 2019-06-05 12:55:00

Но если сервер оракула не отстает от времени сервера, то это может быть

php new Datetime()->format('Y-m-d H:i:s') = 2019-06-05 12:55:00
oracle to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') <=> 2019-06-05 12:55:00

Поскольку sysdate оракула может быть не только больше, но и меньше, могут происходить странные вещи. Поэтому я изменил сравнение sysdate на «sysdate+1», например:

NVL(h.VALIDUNTIL,sysdate+1)

Поскольку это замена значения NULL, возможно, что в будущем это все равно приведет к желаемым результатам.

Другие вопросы по теме