postgresql – 当日期无效时引发错误
我想要做的是在日期超出支持范围的情况下提高超出范围的错误,例如类型转换.
我在CentOS上使用PostgreSQL-9.1.6.问题如下…… postgres=# select to_date('20130229','yyyymmdd'); to_date ------------ 2013-03-01 (1 row) 但我想看到的输出是: postgres=# select '20130229'::date; ERROR: date/time field value out of range: "20130229" 浏览网页我发现an informative page.所以我确实将IS_VALID_JULIAN添加到to_date的函数体中,将下面标记的四行添加到formatting.c: 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; do_to_timestamp(date_txt,fmt,&tm,&fsec); + if (!IS_VALID_JULIAN(tm.tm_year,tm.tm_mon,tm.tm_mday)) + ereport(ERROR,+ (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),+ errmsg("date out of range: "%s"",text_to_cstring(date_txt)))); result = date2j(tm.tm_year,tm.tm_mday) - POSTGRES_EPOCH_JDATE; PG_RETURN_DATEADT(result); } 然后我重建了PostgreSQL: pg_ctl -m fast stop # 1. stopping pgsql vi src/backend/utils/adt/formatting.c # 2. using the version above rm -rf /usr/local/pgsql/* # 3. getting rid of all bin files ./configure --prefix=/usr/local/pgsql --enable-nls --with-perl --with-libxml --with-pam --with-openssl make && make install # 4. rebuilding source pg_ctl start # 5. starting the engine 我的bin目录信息如下. [/home/postgres]echo $PATH /usr/lib64/qt-3.3/bin: /usr/local/bin: /bin: /usr/bin: /usr/local/sbin: /usr/sbin: /sbin: /home/postgres/bin: /usr/bin: /usr/local/pgsql/bin: /usr/local/pgpool/bin: /usr/local/pgtop/bin/pg_top: [/home/postgres]which pg_ctl /usr/local/pgsql/bin/pg_ctl [/home/postgres]which postgres /usr/local/pgsql/bin/postgres [/usr/local/bin]which psql /usr/local/pgsql/bin/psql 但在再次检查to_date后,结果仍然相同. postgres=# select to_date('20130229','yyyymmdd'); to_date ------------ 2013-03-01 (1 row) 我错过了什么吗? 解决方法
您可以编写自己的to_date()函数,但必须使用其模式限定名称来调用它. (我使用了“公共”模式,但没有什么特别之处.)
create or replace function public.to_date(any_date text,format_string text) returns date as $$ select to_date((any_date::date)::text,format_string); $$ language sql 使用裸函数名称执行本机to_date()函数. select to_date('20130229','yyyymmdd'); 2013-03-01 使用模式限定名称执行用户定义的函数. select public.to_date('20130229','yyyymmdd'); ERROR: date/time field value out of range: "20130229" SQL state: 22008 我知道这不是你想要的.但是. . . >它比从源重建PostgreSQL更简单. 但是,需要审查新的SQL和PLPGSQL.我不希望开发人员每次都记得写public.to_date().如果使用版本控制,则可以编写预先提交挂钩以确保仅使用public.to_date(). 本机to_date()函数具有我没有看到记录的行为.您不仅可以在2月29日拨打电话,也可以在2月345日或9999年2月拨打电话. select to_date('201302345','yyyymmdd'); 2014-01-11 select to_date('2013029999','yyyymmdd'); 2040-06-17 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |