Точность оракула при сравнении двух дат в SQL - PullRequest
0 голосов
/ 30 мая 2019

Это две процедуры, которые выполняются по порядку. В первой процедуре временная метка системного времени равна 2019/5/30 12:02:58.100. Sql, как показано ниже

insert into A(xxx,xxx,cdate) values(xxx,xxx,sysdate)

И я нахожу поле cdate этой вставленной строки 2019/5/30 12:02:58 без миллисекунды.

А затем запускается вторая процедура, временная метка системного времени равна 2019/5/30 12:02:58.200. SQL как показано ниже

select xxx from A where cdate<sysdate

Это не возвращает ни одного результата. Это странно, потому что я только что вставил строку с помощью cdate 2019/5/30 12:02:58. Это должно быть меньше sysdate.

  1. Когда Oracle сохраняет значение даты, например 2019/5/30 12:02:58, оно выбрасывает миллисекунды или просто сохраняет его в фоновом режиме и не показывает его?

  2. При сравнении cdate<sysdate, какие два значения он использует? Я предполагаю, что он использует 2019/5/30 12:02:58 < 2019/5/30 12:02:58, так что это возвращает false.

Ответы [ 2 ]

1 голос
/ 30 мая 2019

Когда Oracle хранит значение даты, например 2019/5/30 12:02:58, оно выбрасывает миллисекунды или просто сохраняет его в фоновом режиме и не показывает его?

У значения даты неткомпонент миллисекунды, чтобы выбросить.sysdate возвращает тип данных DATE :

Этот тип данных содержит поля даты и времени YEAR, MONTH, DAY, HOUR, MINUTE и SECOND.У него нет дробных секунд или часового пояса.

В ваших процедурах вы смотрите значение TIMESTAMP:

Этот тип данных содержит поля даты и времени YEAR, MONTH, ДЕНЬ, ЧАС, МИНУТА и ВТОРОЙ.Он содержит доли секунды, но не имеет часового пояса.

... или вариант, который имеет часовой пояс, такой как TIMESTAMP WITH TIME ZONE, как возвращено systimestamp:

Этот тип данных содержит поля даты и времени: ГОД, МЕСЯЦ, ДЕНЬ, ЧАС, МИНУТА, ВТОРОЙ, TIMEZONE_HOUR и TIMEZONE_MINUTE.Он имеет доли секунды и явный часовой пояс.


При сравнении cdate<sysdate, какие два значения он использует?Я предполагаю, что он использует 2019/5/30 12:02:58 < 2019/5/30 12:02:58, так что это возвращает ложь.

Поскольку ваш оператор вставки использует sysdate, на данном этапе не имеет значения, определено ли cdate как DATEили TIMESTAMP, если последний, то часть доли секунды просто обрезается до нуля.И sysdate также возвращает DATE, так что да, он либо делает:

2019-05-30 12:02:58 < 2019-05-30 12:02:58

или

2019-05-30 12:02:58.000 < 2019-05-30 12:02:58

, что может включать неявное приведение.В любом случае результат действительно ложный.


Если вы хотите сравнить значения, которые могут быть в пределах одной секунды, то вам нужно использовать TIMESTAMP.Определите столбец как один из вариантов TIMESTAMP, а затем используйте systimestamp вместо sysdate как для вставки, так и для сравнения.Все это должны быть метки времени - если какая-либо часть того, что вы делаете, остается в качестве даты, то в какой-то момент дробные секунды будут потеряны, и вы будете в том же положении, в котором находитесь сейчас.

0 голосов
/ 30 мая 2019

Если ваш столбец имеет тип DATE, он не хранит миллисекунды.SYSDATE также не возвращает их.Убедитесь, что ваш столбец является TIMESTAMP с подходящим числом для дробной точности, чтобы хранить нужные миллисекунды, и убедитесь, что вы сравниваете его с SYSTIMESTAMP

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...