检查PostgreSQL源代码中的有效日期

时间:2015-07-29 23:22:09

标签: sql-server postgresql validation date

我有一个远程PG数据源,我无法创建自定义函数。我必须将PG数据转储到MSSQL Server 2008 R2上的unicode表中。我需要一个内联的PostgreSQL语句,用'1900-01-01'代替无效的日期。

我做了大量的谷歌搜索无济于事......谢谢。

3 个答案:

答案 0 :(得分:2)

PostgreSQL的时间戳范围远大于SQL Server的日期时间范围。在PostgreSQL中,'0214-06-19 00:00:00'是有效的时间戳。所以'0214-06-19 00:00:00 BC'。

我不清楚结果应该是日期还是时间戳。但这显示了你应该如何处理PostgreSQL中的问题

with data (ts) as (
  values (timestamp '0214-06-19 00:00:00'), ('1900-01-01 08:00')
)
select 
    ts as source_ts, 
    case when ts < timestamp '1900-01-01' then timestamp '1900-01-01' 
         else ts 
    end as altered_ts
from data;
source_ts             altered_ts
--
0214-06-19 00:00:00   1900-01-01 00:00:00
1900-01-01 08:00:00   1900-01-01 08:00:00

假设1900年之前的每个日期都应该是1900-01-01,那是有风险的。值“0214-06-19”可能是2014-06-19的拼写错误。

答案 1 :(得分:0)

使用CTE更容易编写(和读取)SQL中更复杂的算法:

with 
    syntax as (
        select str, 
            str ~ '^\d{4}-\d{2}-\d{2}$' as syntax_ok,
            split_part(str, '-', 1) as syy,
            split_part(str, '-', 2) as smm,
            split_part(str, '-', 3) as sdd
        from test_date),
    toint as (
        select *,
            case when syntax_ok then syy::int else 1900 end yy,
            case when syntax_ok then smm::int else 1 end mm,
            case when syntax_ok then sdd::int else 1 end dd
        from source),
    semantics as (
        select *,
            case
            when mm in (1,3,5,7,8,10,12) then dd between 1 and 31
            when mm in (4,6,9,11) then dd between 1 and 30
            when mm = 2 then 
                case when yy/4*4 = yy and (yy/100*100 <> yy or yy/400*400 = yy)
                then dd between 1 and 29
                else dd between 1 and 28 end
            else false end as valid
        from toint),
    result as (
        select str,
            case when syntax_ok and valid then str
            else '1900-01-01' end as date
        from semantics)
select * from result

第一个查询检查语法并将str拆分为三个部分,第二个查询将部分转换为整数,第三个查询检查语义。 SQLFiddle

您的评论显示您不需要进行彻底的检查,但我认为此查询可以根据您的喜好轻松定制。

答案 2 :(得分:0)

转换为char,然后格式化您想要的方式

SELECT TO_CHAR(date_time_column, 'YYYY-MM-DD') AS mssql_date_format
FROM table_name 
WHERE -- your condition here

-- results like: 1900-01-01

在这里阅读更多内容