Вот мои выводы ... кажется, что вы столкнулись с ошибкой, вызванной тем фактом, что рассчитанные даты, по-видимому, имеют внутреннее представление, отличное от дат "базы данных". Я нашел обходной путь, так что продолжайте читать.
В моей установке oracle dev (Oracle 11g Enterprise Edition, выпуск 11.2.0.4.0 - 64-битная версия) у меня возникла та же проблема.
НО ... Если я создаю физическую таблицу, содержащую ваши тестовые данные:
create table test_data as
SELECT LEVEL ID,
TRUNC(SYSDATE) + LEVEL MyDate,
to_char(LEVEL) STRING
FROM dual
CONNECT BY LEVEL < 5
и затем запустите оператор «cast cast» для этой физической таблицы, он работает как положено:
-- this one works perfectly
SELECT CAST(COLLECT(MyDate) AS date_array) from test_data
но все эти примеры по-прежнему НЕ работают:
-- here I just added 1 .. and it doesn't work
SELECT CAST(COLLECT(MyDate + 1) AS date_array)
from test_data
-- here I am extracting sysdate, instead of a physical column... and it doesn't work
SELECT CAST(COLLECT(sysdate) AS date_array)
from test_data
Такое ощущение, что оракул не думает, что вычисленные даты - это то же самое, что и физические даты
Итак, я попытался «убедить» оракула, что данные, которые я предоставляю, на самом деле являются обычным значением DATE, используя явное приведение ... и EUREKA! это делает работу правильно:
WITH q AS
(SELECT LEVEL ID,
-- this apparently unnecessary cast does the trick
CAST( TRUNC(SYSDATE) + LEVEL AS DATE) MyDate,
to_char(LEVEL) STRING
FROM dual
CONNECT BY LEVEL < 5)
SELECT CAST(COLLECT(MyDate) AS date_array)
FROM q
Да ... но почему ??
Действительно, кажется, что эти два значения не совсем одно и то же, даже если видимые значения на самом деле одинаковы:
select sysdate, cast (sysdate as date) from dual
Итак, я выкопал внутреннее представление двух значений, применив к ним функцию «dump»:
select dump(sysdate), dump(cast (sysdate as date)) from dual
и вот результаты, которые я получил:
DUMP(SYSDATE ) -> Typ=13 Len=8: 226,7,11,9,19,20,47,0
DUMP(CAST(SYSDATEASDATE) as DUAL) -> Typ=12 Len=7: 120,118,11,9,20,21,48
Внутренне они выглядят как два совершенно разных типа данных! один тип 12, а другой тип 13 ... и они имеют разную длину и представление.
В любом случае, я обнаружил кое-что еще .. кажется, кто-то еще заметил это: https://community.oracle.com/thread/4122627
На вопрос есть ответ, указывающий на этот документ: http://psoug.org/reference/datatypes.html
, в котором содержится длинное примечание о датах ... выдержка из него гласит:
"Что случилось? Указанная выше информация неверна или DUMP ()
функция не обрабатывает значения DATE? Нет, вы должны посмотреть на "Typ ="
значения, чтобы понять, почему мы видим эти результаты. ". Тип данных
возвращается 13, а не 12, внешний тип данных DATE. Это происходит
потому что мы полагаемся на функцию TO_DATE! Внешний тип данных 13 является
внутренняя c-структура, длина которой варьируется в зависимости от того, как
c-компилятор представляет структуру. Обратите внимание, что значение Len = 8
а не 7. Тип 13 не является частью опубликованных интерфейсов 3GL для
Oracle и используется для вычисления даты в основном в PL / SQL
операции. Обратите внимание, что тот же результат можно увидеть при DUMPing
значение SYSDATE. "
В любом случае, повторюсь: я думаю, что это ошибка, но, по крайней мере, я нашел обходной путь: используйте явное приведение к DATE.