我有一个Oracle查询
SELECT to_timestamp('29-03-17 03:58:34.312000000 PM','DD-MM-RR HH12:MI:SS.FF AM')
FROM DUAL
我想转换为SQL Server,我需要保留Oracle日期字符串,即'29-03-17 03:58:34.312000000 PM'
:
SELECT
CONVERT(DATETIME, REPLACE(REPLACE('29-03-2017 03:58:34.312000000 PM','-', '/'),'000000 ', ''), 131)
我尝试了上述查询,因为131格式非常匹配'29 -03-17 03:58:34.312000000 PM'格式'dd / mm / yyyy hh:mi:ss:mmmAM',但唯一的区别在于年份。
在Oracle年份是17年,SQL Server年份是2017年。我需要在年份前加20来使其成为2017年。此查询将转换为Hijri日期时间。我需要格里高利日期时间格式。
这是文档。
https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql
我需要将Oracle格式的字符串日期转换为SQL Server等效日期。有没有什么方法可以提到像'dd / mm / yyyy hh:mi:ss:mmmAM'这样的格式,而不是在转换函数中提到像131,101,102这样的日期格式代码。
答案 0 :(得分:1)
您可以这样尝试:
DECLARE @oracleDT VARCHAR(100)='29-03-17 03:58:34.312000000 PM';
SELECT CAST('<x>' + @oracleDT + '</x>' AS XML).value(N'(/x/text())[1]','datetime');
看来,XML隐含地能够正确地执行此操作......
它适用于我的(德语)系统,但是如果您设置了正确的日期格式,则可以强制执行此操作(注意当前作业的副作用!)
尝试此操作,然后移除--
以尝试其他日期格式。或者尝试使用GERMAN
:
SET LANGUAGE ENGLISH;
SET DATEFORMAT mdy;
--SET DATEFORMAT ymd;
--SET DATEFORMAT dmy;
DECLARE @oracleDT VARCHAR(100)='01-02-03 03:58:34.312000000 PM';
SELECT CAST('<x>' + @oracleDT + '</x>' AS XML).value(N'(/x/text())[1]','datetime');
您可以在所有部分中拆分字符串并构建可转换格式,如下所示:
DECLARE @oracleDT VARCHAR(100)='29-03-17 03:58:34.312000000 PM';
WITH AllParts(Casted) AS
(
SELECT CAST('<x>' + REPLACE(REPLACE(REPLACE(REPLACE(@oracleDT,'.','-'),' ','-'),':','-'),'-','</x><x>') + '</x>' AS XML)
)
SELECT CONVERT
(DATETIME,
DATENAME(MONTH,'2000'+Casted.value(N'x[2]/text()[1]','nvarchar(max)')+'01') + ' '
+ Casted.value(N'x[1]/text()[1]','nvarchar(max)') + ' '
+ N'20' + Casted.value(N'x[3]/text()[1]','nvarchar(max)') + ' '
+ Casted.value(N'x[4]/text()[1]','nvarchar(max)') + ':'
+ Casted.value(N'x[5]/text()[1]','nvarchar(max)') + ':'
+ Casted.value(N'x[6]/text()[1]','nvarchar(max)') + ':'
+ LEFT(Casted.value(N'x[7]/text()[1]','nvarchar(max)'),3)
+ Casted.value(N'x[8]/text()[1]','nvarchar(max)'),109)
FROM AllParts
答案 1 :(得分:0)
虽然我并不真正理解使用不适合转换的字符串格式的必要性,但您可以将字符串分成几部分,然后通过将部分相互添加来构建它。如果前8个字符使用格式样式5转换为datetime2,则为基础部分。
select
t
, convert(varchar, converted ,121) converted
from (
select '29-03-17 03:58:34.312000000 PM' as t
) t
cross apply (
select
convert(datetime2,substring(t,1,8),5) dt2
, case when right(t,2) = 'PM' then convert(smallint,substring(t,10,2)) + 12
else convert(smallint,substring(t,10,2))
end hh
, convert(smallint,substring(t,13,2)) mi
, convert(smallint,substring(t,16,2)) ss
, convert(int,substring(t,19,9)) ns
) ca
cross apply (
select
dateadd(hh,hh,dateadd(mi,mi,dateadd(ss,ss,dateadd(ns,ns,dt2))))
as converted
) ca2
;
注意我可以在第二个交叉应用中使用第一个交叉应用(dt1,hh,mi,ss,ns)的列别名来形成转换后的datetime2值。
+--------------------------------+-----------------------------+
| t | converted |
+--------------------------------+-----------------------------+
| 29-03-17 03:58:34.312000000 PM | 2017-03-29 15:58:34.3120000 |
+--------------------------------+-----------------------------+