2017-09-08 1 views
1

서로 다른 형식의 날짜가있는 하나의 varchar 데이터 형식 열이있는 SQL 테이블이 있습니다.다른 datetime 형식의 데이터를 다른 테이블의 datetime 열로 변경하는 방법

데이터

예 :

2017-06-30 09:40:05.130, 
2017-08-21 12:52:23.063000000, 
26/4/2016 00:00:00, 
5/4/2016 00:00:00 

난 날짜 데이터 형식 다른 SQL 테이블 컬럼이 컬럼 (VARCHAR 데이터 유형)로부터 데이터를로드 할 필요가있다. 나는 다음과 같은 쿼리

Select 
convert(datetime,convert(char(19),'2017-08-21 12:52:23.063000000')) 

Select 
convert(datetime,convert(char(19),'26/4/2016 00:00:00'),103) 

아무도 나에게 다른 형식으로 날짜를 변환하는 일반적인 단일 쿼리를 도와 드릴까요 시도?

+0

두 번째 항목이 흥미로운 형식으로되어 ... 심지어'DATETIME2'는 소수점지나 7 곳을 줄 것이다, 당신은 9 – Eli

+0

가 얻을 수있는 방법이 없습니다 있습니다 모든 문자열에 대해 작동하는 실제 날짜 시간에 대한 날짜의 문자열 표현. 이것이 날짜가 문자열로 저장되어서는 안되는 이유 중 하나입니다. 당신은 아마도 이것을 그룹으로해야 할 것입니다. 하나의 형식에 맞는 것을 찾은 다음 변환 한 다음 다른 그룹을 하나씩 변환하십시오. 그러면 마지막 그룹이있게 될 것입니다 .... "나는 이것이 날짜가 아니기 때문에 이것을 어떻게 처리해야할지 모르겠다."그룹. –

+0

기본적으로 서로 다른 소스 csv 파일에서 이러한 날짜를 얻고 있습니다. 처음에는 varchar datatype.then을 사용하여 스테이지 테이블에로드하고 datetime datatype의 다른 테이블을로드하려고 시도합니다. CSV 원본 파일은 각 파일마다 다른 형식을 사용하고 있습니다. – user6355550

답변

0

그것은 추한 작업입니다, 그러나 이것은 내가 생각할 수있는 최선입니다 :

select convert(datetime2, '9/20/2017') 
select convert(datetime2, '2017-06-30 09:40:05.130') 
select convert(datetime2, '2017-08-21 12:52:23.063000000') 
select convert(datetime, '5/4/2016 00:00:00') 

그러나, 명심, @Eli는 의견에서 지적했듯이, 두 번째 예는 세차 운동을 놓칠 수 있습니다. 또한 '26/4/2016 00:00:00 '을 처리하지 않습니다. (순서대로) 다음과 같이 반환됩니다

위의 예 :

2017-09-20 00:00:00.0000000 
2017-06-30 09:40:05.1300000 
2017-08-21 12:52:23.0630000 
2016-05-04 00:00:00.000 
+0

, 답장을 보내 주셔서 감사합니다. – user6355550

0

내가 쿼리 다음과 같은 시도는, 내가 모두와 함께 노력

declare @col varchar(100)='2017-08-21 12:52:23.063000000' 

Select 
    case 
     when isdate(convert(char(19),@col))=1 then convert(datetime,convert(char(19),@col)) 
     else convert(datetime,convert(char(19),@col),103) 
    end Col 

내 경우에는 다른 형식으로 나를 위해 일 위 날짜, 그것은 일했다.

0

오류 처리를 사용하여 실패한 변환을 무시해야하므로 각 데이터 행을 처리하기 위해 커서가 필요합니다. 이렇게하면 변환 할 수있는 값을 조작하고 변환 오류로 인해 루프가 중단되지 않고 변환 할 수없는 값을 볼 수 있습니다. 작은 예 :

DECLARE @tbl TABLE (dat NVARCHAR(64)) 
INSERT INTO @tbl (dat) VALUES ('2017-06-30 09:40:05.130') 
INSERT INTO @tbl (dat) VALUES ('26/4/2016 00:00:00') 
INSERT INTO @tbl (dat) VALUES ('2017-08-21 12:52:23.063000000') 
INSERT INTO @tbl (dat) VALUES ('5/4/2016 00:00:00') 
DECLARE @cdat NVARCHAR(64) 

DECLARE c CURSOR LOCAL FAST_FORWARD READ_ONLY FOR 
    SELECT dat FROM @tbl 
OPEN c 
FETCH NEXT FROM c INTO @cdat 
WHILE @@fetch_status = 0 BEGIN 

    BEGIN TRY 
     /*convert and do the job*/ 
     SELECT CONVERT(DATETIME2,@cdat)--into normal table 
    END TRY 
    BEGIN CATCH 
     /*handle failed conversions*/ 
     SELECT @cdat --into failstable? 
     PRINT 'failed conversion, data:' + @cdat 
    END CATCH 

    FETCH NEXT FROM c INTO @cdat 
END 
CLOSE c 
DEALLOCATE c 
0

당신은 SQL 서버 2012 이상을 사용하는 경우 TRY_PARSE 기능을 사용할 수 있습니다. 이것은 SQL 네이티브 함수가 아니라 .NET 런타임 종속 함수입니다. 또한 TRY_CONVERTTRY_CAST에는없는 현명한 데이터 문화를 분석 할 수 있습니다. 성능 오버 헤드가 발생할 수 있지만 지정된 데이터 형식으로 데이터를 구문 분석하는 것이 가장 좋습니다.

declare @t table (dates nvarchar(50)); 
insert into @t values 
('2017-06-30 09:40:05.130'), 
('2017-08-21 12:52:23.063000000'), 
('26/4/2016 00:00:00'), 
('5/4/2016 00:00:00') ; 

select 
    try_parse(dates as datetime) parsed_dates , 
    dates 
from @t; 

--result 

    parsed_dates  dates 
    30.06.2017 09:40:05 2017-06-30 09:40:05.130 
    21.08.2017 12:52:23 2017-08-21 12:52:23.063000000 
    NULL    26/4/2016 00:00:00 
    04.05.2016 00:00:00 5/4/2016 00:00:00 

see demo

관련 문제