ORA-01861: литерал не соответствует строке формата, несмотря на использование функции to_date - PullRequest
0 голосов
/ 02 апреля 2019

Обнаружена эта ошибка на модуле EXCEL VBA. На интерфейсе Oracle 11g он работает хорошо.

select 
        "schema_name", "table_name", "bundle_name", "text_file", "sequence_no", 
                    lastupdateapplied, "next_sat_date","prev_sat_date", TO_DATE(SYSDATE,'DD-MM-YYYY'),
        CASE 
                WHEN ("schema_name"='EDM_V1' OR "schema_name"='FF_V3' OR "schema_name"='SYM_V1') and 
                            ("next_sat_date"-lastupdateapplied<=0 OR 
                            lastupdateapplied-"prev_sat_date">=0) 
                then 'EVERYTHING LOOKS OK HERE.'
                WHEN  ("schema_name"='FP_V2' OR "schema_name"='FE_V4' OR "schema_name"='REF_V2') and 
                            (lastupdateapplied - TO_DATE(SYSDATE,'DD-MM-YYYY') =0)
                then 'EVERYTHING LOOKS OK HERE.'
                Else 'PLEASE CHECK THE SCHEDULER FOR THIS FEED.' END as    "VERIFICATION_NOTE"
from
        ( 
            select 
                    UPPER(ds."schema_name") as "schema_name", UPPER(ds."table_name") as "table_name", ds."bundle" as "bundle_name", ds."text_file" as "text_file", 
                    ds."sequence" as "sequence_no", TO_DATE(s2.end_time,'DD-MM-YYYY') as lastupdateapplied, TO_DATE(next_day(SYSDATE,'SATURDAY'),'DD-MM-YYYY') as "next_sat_date",  
                    TO_DATE(next_day(SYSDATE,'SATURDAY')-(INTERVAL '7' DAY + INTERVAL '1' SECOND),'DD-MM-YYYY') AS "prev_sat_date"
            from FDS_FDS_DATA_SEQUENCES ds 
            Join 
            (   select "table_name", "bundle", "text_file", max("end_time") as end_time 
                from FDS_FDS_FILE_HISTORY 
                where "file_type" = 'full' 
                group by "table_name", "bundle", "text_file") s 
             on s."bundle" = ds."bundle" and s."table_name" = ds."table_name" and s."text_file" = ds."text_file"
            Join 
            (   select "table_name", "bundle", "text_file", max("end_time") as end_time 
                from FDS_FDS_FILE_HISTORY 
                where "file_type" = 'update' 
                group by "table_name", "bundle", "text_file") s2 
            on s2."bundle" = ds."bundle" and s2."table_name" =  ds."table_name" and s2."text_file" = ds."text_file" 
Order by 
            ds."schema_name" asc, ds."bundle" asc, s2.end_time desc )

Ожидаемый результат: я не должен получить ошибку, а фактический результат ===>, когда я выполняю тот же запрос в ORACLE SQL Developer, он работает отлично, но не работает в модуле Excel VBA.

1 Ответ

1 голос
/ 02 апреля 2019

несмотря на использование функции to_date

На самом деле это из-за с использованием функции to_date(). У вас есть такие вещи:

TO_DATE(SYSDATE,'DD-MM-YYYY')
TO_DATE(s2.end_time,'DD-MM-YYYY')
TO_DATE(next_day(SYSDATE,'SATURDAY'),'DD-MM-YYYY')
TO_DATE(next_day(SYSDATE,'SATURDAY')-(INTERVAL '7' DAY + INTERVAL '1' SECOND),'DD-MM-YYYY')

Второй из этих может быть в порядке, но только если sd.end_time хранится в виде строки - что почти наверняка не должно быть.

Для остальных трех, по крайней мере, вы передаете что-то , которое уже является датой , в функцию, предназначенную для преобразования строки в дату. Итак, вы действительно делаете, например:

TO_DATE(TO_CHAR(SYSDATE),'DD-MM-YYYY')

и поскольку у этого неявного TO_CHAR() нет модели формата, он будет использовать настройки NLS вашего сеанса, в частности NLS_DATE_FORMAT. Вы видите, что это работает в одной среде, потому что настройки там фактически означают, что он делает:

TO_DATE(TO_CHAR(SYSDATE, 'DD-MM-YYYY'),'DD-MM-YYYY')

тогда как в другом сеансе это может быть эффективно:

TO_DATE(TO_CHAR(SYSDATE, 'DD-MON-RR'),'DD-MM-YYYY')

... что потеряло бы столетие, оставив значение даты в году 0019 вместо 2019 года; или

TO_DATE(TO_CHAR(SYSDATE, 'YYYY-MM-DD'),'DD-MM-YYYY')

который выдает "ORA-01861: литерал не соответствует строке формата", как вы видите.

Хотя вы можете попытаться заставить настройки NLS на каждом клиенте и приложении соответствовать тому, что вы делаете, в конечном итоге вы ошибетесь, и вы должны делать это преобразование вообще. Просто используйте SYSDATE и другие, рассчитанные напрямую; или если вы пытаетесь получить даты с установленным на полночь временем, обрежьте их:

trunc(SYSDATE)
trunc(s2.end_time)
trunc(next_day(SYSDATE,'SATURDAY'))
trunc(next_day(SYSDATE,'SATURDAY')-(INTERVAL '7' DAY + INTERVAL '1' SECOND))

Также обратите внимание, что вторым аргументом next_day() является название дня или сокращение на языке даты текущего сеанса, поэтому тот, кто запускает это из сеанса на другом языке, также увидит ошибки (например, «ORA-01846: не действительный день недели ").

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