sql语言是postgressql。
函数只处理了
中国格式 : xxxx年-xx月-xx日
美国格式: mm/dd/yyyy, September 04,1991, September 1991, sept 04, 1991
uunix格式: yyyy/mm/dd, yyyy/mm, 1991-01-1, 1991-1 , 1991-01
其他格式可以自行添加
预期的日期格式是: 1991/1/1 。 不能有0,即1991/01/01 是失败的
函数返回的是: " ‘预期格式’,年,月"
查找str2在str1出现的位置。num是出现的次数,默认是1。例如num=2,就是str2在str1第二次出现的位置。start_position是起始的位置下标,默认是从头开始即 1。
若str2在str1找不到,则返回0
instr('123456', '2') -- 结果是: 2. 位置索引值是从1开始
instr('123456', '2' , 2) -- 结果是0 , 因为2 只出现一次
截取字符串, 从str1 的 start_position开始截取, 截取长度是 length。length不填就是截取到字符串的最右边。
例如 start_position=2, length=3, str1= ‘’12345678‘’
substr('123456', 2, 3) -- 结果是: 234. 因为postgres是下标索引是1开始
substr('123456', 1, 3) -- 结果是: 123. 因为postgres是下标索引是1开始
substr('123456', 0, 3) -- 结果是: 123. 0也当成1
substr('123456', 2) -- 结果是: 23456. 长度值不填,默认就是截取到最右边
查看str1 是否 符合 规则 str2.
str2是正则表达式: ^ 表示开头 ,$ 表示结尾。/d 表示数字 0-9,[0-9]也是表达数字,可读性更好。 | 是或的意思。
'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])$') 的规则就是, 19xx,18xx, 20xx 。xx代表数字的任意值
华为gauss DB(DWS)中的字符串切分函数。 可以使用你自己sql相似的函数。
将 str1 按照 str2 切分, 并取切分后结果集合的第几个值。
-- 将'1,2,3'用 ','切分, 并取切分后结果的第二个值。
split_part('1,2,3' , ',' , 2) -- 结果是2
去除字符串收尾的空格,避免影响 split_part 以空格切分字符串。
返回月值, 确保没有0 。 因为清洗的预期是不要0
-- 返回 'birthday,birthday_year,birthday_month'
CREATE OR REPLACE FUNCTION aml.f_get_date_str(birthday_str character varying(500))
RETURNS character varying
LANGUAGE plpgsql
STABLE NOT FENCED SHIPPABLE -- 华为gausDB DWS的独有, postgres不用
AS $$
DECLARE
p_birthday_str VARCHAR2(500);
text_var1 text;
text_var2 text;
text_var3 text;
BEGIN
SELECT
CASE -- 处理只有年份数字的 1988 、1978
WHEN regexp_like (trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])$') > 0
then concat_ws(',', trim(birthday_str)
, trim(birthday_str)
, ' '
)
-- 处理1988/05/15 或 1988/5/15 , 或1988/5/5
WHEN regexp_like(trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])(\/)([1-9]|[0][1-9]|[1][0-2])(\/)([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])$') > 0
then concat_ws(',', year(birthday_str) || '/' || month(birthday_str) || '/' || day(birthday_str)
, year(birthday_str)
, month(birthday_str)
)
-- 处理1988/05,1988/5 , 确保 没有0开头, 所以调用year,month函数再组装
WHEN regexp_like(trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])(\/)([1-9]|[0][1-9]|[1][0-2])$') > 0
then concat_ws(',', year(trim(birthday_str) || '/01') || '/' || month(trim(birthday_str) || '/01')
, year(trim(birthday_str) || '/01')
, month(trim(birthday_str) || '/01')
)
-- 处理mm/dd/yyyy
WHEN regexp_like(trim(birthday_str),'^([1-9]|[0][1-9]|[1][0-2])(\/)([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(\/)([1][8-9][0-9][0-9]|[2][0][0-9][0-9])$') > 0
then concat_ws(',', year(birthday_str) || '/' || month(birthday_str) || '/' || day(birthday_str)
, year(birthday_str)
, month(birthday_str)
)
-- 处理mm/yyyy , 确保 没有0开头, 所以调用year,month函数再组装
WHEN regexp_like(trim(birthday_str),'^([1-9]|[0][1-9]|[1][0-2])(\/)([1][8-9][0-9][0-9]|[2][0][0-9][0-9])$') > 0
then concat_ws(',', year(replace(trim(birthday_str),'/','/01/')) || '/' || month(replace(trim(birthday_str),'/','/01/'))
, year(replace(trim(birthday_str),'/','/01/'))
, month(replace(trim(birthday_str),'/','/01/'))
)
-- 处理中国格式,
-- xxxx年xx月xx日, -> yyyy/m/d
WHEN regexp_like(trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])(年)([1-9]|[0][1-9]|[1][0-2])(月)([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(日)$') > 0
then concat_ws(',', year(replace(replace(replace(birthday_str,'年','/'),'月','/'),'日','')) || '/' || month(replace(replace(replace(birthday_str,'年','/'),'月','/'),'日','')) || '/' || day(replace(replace(replace(birthday_str,'年','/'),'月','/'),'日',''))
, year(replace(replace(replace(birthday_str,'年','/'),'月','/'),'日',''))
, month(replace(replace(replace(birthday_str,'年','/'),'月','/'),'日',''))
)
-- xxxx年xx月 -> yyyy/m
WHEN regexp_like(trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])(年)([1-9]|[0][1-9]|[1][0-2])(月)$') > 0
then concat_ws(',', year(trim(replace(replace(birthday_str,'年','/'),'月','/')) || '01') || '/' || month(trim(replace(replace(birthday_str,'年','/'),'月','/')) || '01')
, year(trim(replace(replace(birthday_str,'年','/'),'月','/')) || '01' )
, month(trim(replace(replace(birthday_str,'年','/'),'月','/')) || '01')
)
-- xxxx年xx -> yyyy/m
WHEN regexp_like(trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])(年)([1-9]|[0][1-9]|[1][0-2])$') > 0
then concat_ws(',', year(trim(replace(birthday_str,'年','/')) || '/01') || '/' || month(trim(replace(birthday_str,'年','/')) || '/01')
, year(trim(replace(birthday_str,'年','/')) || '/01')
, month(trim(replace(birthday_str,'年','/')) || '/01')
)
-- xxxx年
WHEN regexp_like(trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])(年)$') > 0
then concat_ws(',', replace(birthday_str,'年','')
, replace(birthday_str,'年','')
, ' ' )
-- 处理1988-05-15 或 1988-5-15 , 或1988-5-5
WHEN regexp_like(trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])(\-)([1-9]|[0][1-9]|[1][0-2])(\-)([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])$') > 0
then concat_ws(',', year(replace(birthday_str,'-','/')) || '/' || month(replace(birthday_str,'-','/')) || '/' || day(replace(birthday_str,'-','/'))
, year(replace(birthday_str,'-','/'))
, month(replace(birthday_str,'-','/'))
)
-- 处理1988-05
WHEN regexp_like(trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])(\-)([1-9]|[0][1-9]|[1][0-2])$') > 0
then concat_ws(',', year(trim(replace(birthday_str,'-','/')) || '/01') || '/' || month(trim(replace(birthday_str,'-','/')) || '/01')
, year(trim(replace(birthday_str,'-','/')) || '/01')
, month(trim(replace(birthday_str,'-','/')) || '/01')
)
-- 处理19880515
WHEN regexp_like(trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])([0][1-9]|[1][0-2])([0][1-9]|[1-2][0-9]|[3][0-1])$') > 0
then concat_ws(',', year(birthday_str) || '/' || month(birthday_str) || '/' || day(birthday_str)
, year(birthday_str)
, month(birthday_str)
)
-- 处理198805,20xx05 , 补齐日的值 例如:01
WHEN regexp_like(trim(birthday_str),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])([0][1-9]|[1][0-2])$') > 0
then concat_ws(',', year(trim(birthday_str) || '01') || '/' || month(trim(birthday_str) || '01')
, year(trim(birthday_str) || '01')
, month(trim(birthday_str) || '01')
)
-- 处理美国时间格式(英文),'September 04, 1952' ,'Sept 04, 1952', 'September, 1952' , 'Sept, 1952'
WHEN trim(split_part(split_part(birthday_str,',',1),' ',1)) in ('January' ,'February' ,'March' , 'April' , 'May' , 'June' , 'July' , 'August' ,'September' ,'October' ,'November' ,'December', 'Jan' , 'Feb' , 'Mar' ,'Apr' , 'Aug' , 'Sept' , 'Oct' ,'Nov' , 'Dec')
and regexp_like(trim(split_part(birthday_str,',',2)),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])$') > 0 -- 判断年份值是否合理
then
-- 'September 04, 1952'
case when regexp_like(trim(split_part(split_part(birthday_str,',',1),' ',2)),'^([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])$') > 0 -- 判断日份值是否合理
then concat_ws(',', year(birthday_str) || '/' || month(birthday_str) || '/' || day(birthday_str)
, year(birthday_str)
, month(birthday_str)
)
--不完整,缺少日 'September, 1952' 。 补全日期后(日期数值随意,这里补01),利用函数 year, month,day
when split_part(split_part(birthday_str,',',1),' ',2) is null
then concat_ws(',', year(replace(birthday_str, ',' , '01,')) || '/' || month(replace(birthday_str, ',' , '01,'))
, year(replace(birthday_str, ',' , '01,'))
, month(replace(birthday_str, ',' ,'01,'))
)
end
-- ’September 1952‘ 格式
WHEN trim(split_part(birthday_str,' ',1)) in ('January' ,'February' ,'March' , 'April' , 'May' , 'June' , 'July' , 'August' ,'September' ,'October' ,'November' ,'December', 'Jan' , 'Feb' , 'Mar' ,'Apr' , 'Aug' , 'Sept' , 'Oct' ,'Nov' , 'Dec')
and regexp_like(trim(split_part(birthday_str,' ',2)),'^([1][8-9][0-9][0-9]|[2][0][0-9][0-9])$') > 0 -- 判断年份值是否合理
then concat_ws(',', year(replace(birthday_str, ' ' , ' 01,')) || '/' || month(replace(birthday_str, ' ' , ' 01,'))
, year(replace(birthday_str, ' ' , ' 01,'))
, month(replace(birthday_str, ' ' , ' 01,'))
)
ELSE concat_ws(',', ' ', ' ', ' ')
END birthday_year_month INTO p_birthday_str ;
RETURN (p_birthday_str) ;
EXCEPTION
WHEN others THEN
GET STACKED DIAGNOSTICS text_var1 = RETURNED_SQLSTATE ,
text_var2 = MESSAGE_TEXT ,
text_var3 = PG_EXCEPTION_DETAIL;
RAISE NOTICE E'--- [已处理的 异常代码_RETURNED_SQLSTATE ] : %', text_var1; -- 记录异常信息
RAISE NOTICE E'--- [已处理的 异常简要信息_MESSAGE_TEXT ] : %', text_var2;
RAISE NOTICE E'--- [已处理的 异常详细信息_PG_EXCEPTION_DETAIL ] : %', text_var3;
RETURN (concat_ws(',', ' ', ' ',' ')) ; -- 处理异常的日期数据,直接返回。 例如日和月值不匹配,1955-02-30
END $$
;