将Oracle Datetime格式查询转换为MS SQL Server格式

时间:2017-05-27 09:21:15

标签: sql-server oracle date datetime

我有一个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这样的日期格式代码。

2 个答案:

答案 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 |
+--------------------------------+-----------------------------+

请参阅:http://rextester.com/DZJ42703