Вы не можете использовать нулевой год с to_date('0000-01-01', 'YYYY-MM-DD')
, но, как ни странно, можете с литералом даты date '0000-01-01'
. Само по себе это становится годом -1, но вы можете использовать его для расчетов; и вы также можете добавить интервал, который может быть основан на вашем числовом значении, например:
SELECT DATE '0000-01-01' + NUMTOYMINTERVAL(my_year, 'YEAR') AS my_date
FROM my_table;
Функция numtoyminterval
возвращает null, если аргумент равен null, и добавление этого к фиксированной дате также дает вам ноль:
alter session set nls_date_format = 'SYYYY-MM-DD';
select date '0000-01-01' + numtoyminterval(null, 'YEAR') from dual;
DATE'0000-01-01'+NUMTOYMINTERVAL(NULL,'YEAR')
---------------------------------------------
select date '0000-01-01' + numtoyminterval(2015, 'YEAR') from dual;
DATE'0000-01-01'+NUMTOYMINTERVAL(2015,'YEAR')
---------------------------------------------
2015-01-01
select date '0000-01-01' + numtoyminterval(9999, 'YEAR') from dual;
DATE'0000-01-01'+NUMTOYMINTERVAL(9999,'YEAR')
---------------------------------------------
9999-01-01
select date '0000-01-01' + numtoyminterval(-4712, 'YEAR') from dual;
DATE'0000-01-01'+NUMTOYMINTERVAL(-4712,'YEAR')
----------------------------------------------
-4712-01-01
Это не надежно; все равно будет ошибка, если вы попытаетесь перейти до -4713:
select date '0000-01-01' + numtoyminterval(-4713, 'YEAR') from dual;
SQL Error: ORA-01841: (full) year must be between -4713 and +9999, and not be 0
...
Хотя вы можете избежать этого с помощью контрольного ограничения для столбца. И из-за молчаливого перевода года 0 в -1 вы получите тот же ответ, если ваше значение my_year
равно 0 или -1:
select date '0000-01-01' + numtoyminterval(0, 'YEAR') from dual;
DATE'0000-01-01'+NUMTOYMINTERVAL(0,'YEAR')
------------------------------------------
-0001-01-01
select date '0000-01-01' + numtoyminterval(-1, 'YEAR') from dual;
DATE'0000-01-01'+NUMTOYMINTERVAL(-1,'YEAR')
-------------------------------------------
-0001-01-01
Кейс-подход Гордона Линоффа более надежен, но он может сработать, если вы действительно имеете дело только с «нормальными» положительными годами. А если нет, то это очень интересно...
person
Alex Poole
schedule
21.07.2015
my_year
? - person Alex K.   schedule 21.07.2015my_year NUMBER(4,0) NULL
, включаяNULL
. - person Álvaro González   schedule 21.07.2015