Вывод Oracle TO_CHAR включает BC

Когда я бегу

select *

Я не получаю свою дату, потому что они негативны, и я вижу их с:

Select to_char(start_date,'DD/MM/YYYY AD'),s.*
from LIST s
where start_date<to_date('00010101 00:00:00', 'yyyymmdd hh24:mi:ss')
order by s.start_date desc

Но они пишутся как 22/03/2016 BC

Откуда взялось BC? Кто-нибудь знает, как мое свидание иногда становится отрицательным? Потому что иногда это "нормальные" даты, а иногда они получили БК...


person V.Cullard    schedule 03.08.2016    source источник
comment
Что значит правильно написано? Простейшее объяснение, казалось бы, состоит в том, что любое приложение, которое вставляло эти значения, вставляло даты 2016 г. до н.э. select * преобразует дату в строку, используя nls_date_format вашего сеанса, который, предположительно, не включает суффикс AD/BC. Точно так же дата может выглядеть нормально, если вы отображаете только 2 цифры года, несмотря на то, что год равен 0016, а не 2016.   -  person Justin Cave    schedule 03.08.2016
comment
Или четырехзначное число лет, если вы опустите знак. Вы фильтруете даты ‹ 01-01-0001, поэтому логически все они должны быть до н.э. Вы также можете использовать to_char(start_date,'SYYYY-MM-DD'), который покажет их как -2016. Итак, как говорит Джастин, ваши проблемы, похоже, связаны с тем, что вставляет данные с отрицательными (BC) годами.   -  person Alex Poole    schedule 03.08.2016
comment
Спасибо за ответы, смотрите мое редактирование. Хорошо, ошибка возникает из-за того, что вставляет дату в неправильном формате. Я бродил, не было ли чего с to_char и т.д...   -  person V.Cullard    schedule 03.08.2016
comment
Всякий раз, когда у вас есть сомнения относительно того, что находится в базе данных, а что отображается (например, делает ли to_char() что-то с моими датами), вы можете использовать DUMP, чтобы увидеть, что на самом деле хранится в базе данных. Например, выберите dump(start_date) from s where start_date < to_date(.....) Как хранятся даты, это не тривиально, вам нужно будет посмотреть документацию, чтобы понять вывод, но это покажет вам напрямую, что находится в БД без посредничества to_char() или неявного преобразования в char.   -  person mathguy    schedule 03.08.2016


Ответы (1)


Если ваша модель формата даты явно или через параметр сеанса NLS_DATE_FORMAT не включает знак года или индикатор AD/BC, вы не сможете различить, скажем, 2016 и -2016, если они являются строками.

with t (dt) as (
  select date '2016-03-22' from dual
  union all select date '-2016-03-22' from dual
  union all select date '0001-01-01' from dual
  union all select date '-0001-01-01' from dual
)
select to_char(dt, 'SYYYY-MM-DD') as dt1,
  to_char(dt, 'YYYY-MM-DD') as dt2,
  to_char(dt, 'DD/MM/YYYY') as dt3,
  to_char(dt, 'DD/MM/SYYYY') as dt4, 
  to_char(dt, 'DD/MM/YYYY AD') as dt5
from t;

DT1         DT2        DT3        DT4         DT5         
----------- ---------- ---------- ----------- -------------
 2016-03-22 2016-03-22 22/03/2016 22/03/ 2016 22/03/2016 AD
-2016-03-22 2016-03-22 22/03/2016 22/03/-2016 22/03/2016 BC
 0001-01-01 0001-01-01 01/01/0001 01/01/ 0001 01/01/0001 AD
-0001-01-01 0001-01-01 01/01/0001 01/01/-0001 01/01/0001 BC

Обратите внимание, что столбцы dt2 и dt3 отображаются одинаково для обеих пар положительных и отрицательных значений, хотя фактические даты были разными.

Ваши значения даты не меняются, как вы их отображаете. Они не «становятся отрицательными» — они становятся отрицательными по какой-то причине, и иногда строка, которую вы конвертируете, показывает это. Если вы измените свой NLS_DATE_FORMAT на 'SYYYY-MM-DD', тогда select * также покажет их как отрицательные посредством неявного преобразования с использованием этого параметра NLS.

Если вы ожидаете в своих данных только значения AD, вам необходимо выяснить, как и почему были вставлены значения BC (отрицательные). Это совершенно отдельная проблема, связанная с тем, как вы видите их отображение.

person Alex Poole    schedule 03.08.2016
comment
Я продолжу расследование. Всем спасибо за ответы :) - person V.Cullard; 05.08.2016