Я использую postgreSQL-9.1.6 на CENTOS.
У меня проблема с функцией to_date , например ...
postgres=# select to_date('20130229','yyyymmdd');
to_date
------------
2013-03-01
(1 row)
Поэтому я пытаюсь добавить проверку на выход за пределы допустимой даты.
postgres = # выберите to_date ('20130229', 'ггггммдд');
ОШИБКА: отметка времени вне допустимого диапазона
Я нашел подсказку от здесь, но это не сработало, и я спросил здесь. к сожалению, я не получил ответа.
Наконец, я пришел к другому выводу. Ниже находится My formatting.c , в который добавлено 9 строк, помеченных +
.
Datum
to_date(PG_FUNCTION_ARGS)
{
text *date_txt = PG_GETARG_TEXT_P(0);
text *fmt = PG_GETARG_TEXT_P(1);
DateADT result;
struct pg_tm tm;
fsec_t fsec;
+ int ndays[]={-1,31,28,31,30,31,30,31,31,30,31,30,31};
+ int last_day_of_month;
do_to_timestamp(date_txt, fmt, &tm, &fsec);
+ last_day_of_month = ndays[tm.tm_mon];
+ if (((tm.tm_year & 3) == 0 && ((tm.tm_year % 25) != 0 || (tm.tm_year & 15) == 0)) && tm.tm_mon == 2 )
+ last_day_of_month = ndays[tm.tm_mon] + 1;
+ if( tm.tm_mon > 12 || tm.tm_mon < 1 || tm.tm_mday > last_day_of_month || tm.tm_mday < 1
)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+ errmsg("timestamp out of range")));
result = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) - POSTGRES_EPOCH_JDATE;
PG_RETURN_DATEADT(result);
}
Хотя мой собственный formatting.c работает хорошо, я не уверен, что он работает идеально. Меня беспокоят неожиданные результаты, такие как выдача ошибки против действительной даты.
Любой совет будет очень признателен.
1 ответ
Вы должны сделать это путем исправления кода сервера? Особенно, если этот патч, вероятно, нарушит работающий в настоящее время SQL, и его нужно будет обновить при обновлении PostgreSQL? Это также плохая идея, потому что вы привыкнете ожидать, что to_date
будет работать так, как работает ваш пользовательский to_date
, и все пойдет не так, когда вы будете работать с PostgreSQL без исправлений. Возможно, вы захотите принять во внимание и других людей, которые застряли при работе с вашим пользовательским сервером PostgreSQL. Откуда им знать, что to_date
на самом деле не to_date
, а какая-то модифицированная версия? OTOH, возможно, вы делаете это для обеспечения безопасности работы.
Почему бы не написать свою собственную функцию замены to_date
, называемую say strict_to_date
, которая выполняет преобразование с использованием to_date
, а затем выполняет простую операцию:
string = to_char(to_date_result, 'yyyymmdd')
Сравнение? Если цикл to_date
и to_char
не дает вам исходный результат, вы можете поднять исключение. Конечно, вам нужно решить, что будет делать strict_to_date(null)
, но это легко добавить.
Рассмотрим несколько простых результатов:
=> select to_date('20130229','yyyymmdd');
to_date
------------
2013-03-01
(1 row)
=> select to_char(to_date('20130229','yyyymmdd'), 'yyyymmdd');
to_char
----------
20130301
(1 row)
С '20130229' != '20130301'
у вас есть исключение. Оберните это функцией и сделайте небольшой комментарий о том, почему вы это делаете, и все должны быть счастливы.
Похожие вопросы
Новые вопросы
postgresql
PostgreSQL — это система управления реляционными базами данных (RDBMS) с открытым исходным кодом, доступная для всех основных платформ, включая Linux, UNIX, Windows и OS X. Задавая вопросы, указывайте свою версию Postgres. Обратитесь к dba.stackexchange.com для вопросов, касающихся администрирования или дополнительных функций.
to_date
-to_char
? Я не думаю, что проверка строки отклонит какие-либо действительные даты.