我有一个远程PG数据源,我无法创建自定义函数。我必须将PG数据转储到MSSQL Server 2008 R2上的unicode表中。我需要一个内联的PostgreSQL语句,用'1900-01-01'代替无效的日期。
我做了大量的谷歌搜索无济于事......谢谢。
答案 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
在这里阅读更多内容