파일

2016-09-27 2 views
3

를 열지 않고 csv 파일의 단일 열에서 구분 기호를 제거 내가 가지고있는 csv 파일의 다음과 같은 내용을 여기에파일

은 CSV 파일의 내용은 다음과 같습니다 2015 년

Date_Added|this_flag|Name|DOB|SSN|ID 

5 월 1 일 | Y | 징글 | heimerscmidt | 19,901,002 | 123,456,789 | 3

May 1st, 2015|N|Jingleheimerscmidt|19901002|123456789|3 
May 5th, 2015|Y|Jon|19901001||1 
May 1st, 2015|N|Jon|19901002||1 
May 1st, 2015|Y|Jacob|19901001|234567890|2 
May 5th, 2015|N|Jingleheimerscmidt|19901001|123456789|3 
May 1st, 2015|Y|Jingleheimerscmidt|19901001|123456789|3 

당신이 굵은 이탤릭체 내용에서 볼 수 있듯이, 파이프 연산자에서 떨어져 컨텐츠의 파이프 운영자가 columns.I이 separted입니다 원하는 CSV 파일을 열지 않고 텍스트에서 해당 파이프 연산자를 제거하십시오.

+0

파일을 열지 않고서도? 수동으로 텍스트 편집기를 열지 않고도 열 수 있습니까? 내용을 읽으려면 파일을 열어야합니다. 단일 VARCHAR 값으로 가져 와서 자신의 규칙에 따라 문자열을자를 수 있습니다. 예 : 모든 열을 여러 행으로 분할하고 너무 많은 행이있을 때를 결정한 다음 행을 연결하고 표 형식으로 다시 피벗합니다. – Matt

+1

csv 파일 생성을 제어 할 수 있다면 텍스트 한정자를 추가 할 수 있습니다. 따옴표를 사용하면 텍스트 내부의 파이프가 처리 응용 프로그램 (또는 사용자의 데이터 정리 코드)에 의해 구분 기호와 혼동되지 않습니다. – Jayvee

+0

코드를 변경하거나 수동으로 파일을 열어서 변경해야합니다. – Missy

답변

0

오케이 태그가 붙은 오라클을 알고 있으므로 자신이나 다른 오라클 전문가가이 솔루션을 SQL Server에서 마이그레이션 할 수 있습니다. 나는 오라클이 이러한 각각의 작업을 수행 할 수 있다는 것을 알고 있습니다.

일반적으로 나는 문자열을 분할하는 빠르고/멋진 방법을 원하지만,이 경우 분리 문자 사이에서 문자열의 서수 위치를 유지해야한다고 말하고 싶습니다. 그래서 네가 할 수있는 방법을 생각 했어.

1) 먼저 CSV를 모든 1 열로 임시 테이블에 가져옵니다. 이제 CRLF가 Name 열에서 발견되는 경우 문제가 될 수 있습니다 .... 그러나 사용자가 지정하지 않았기 때문에 그렇지 않은 것으로 가정합니다.

2) 가짜 기본 키로 사용할 테이블에 row_number를 빌드하고 구분 기호가 더 많이 있어야하는시기를 결정하십시오.

3) 재귀 cte를 사용하여 문자열을 행에 유출하고 원래 문자열에서 부분 문자열의 순서를 유지하여 나중에 연결합니다.

4) 결정에 기초를 두는 DENSE_RANK()를 MergePositions 의해 OrdinalPostion을 변경하고 생성하여 그룹에 어떤 행

5) 모든 OrdginalGroup을 결합하는 연결 수단을 사용해서 열 번호로하고 OrdinalGroup을 사용하여 조건부 집계 3 행.

DECLARE @CSV as TABLE (LumpedColumns NVARCHAR(MAX)) 
INSERT INTO @CSV VALUES 
('May 1st, 2015|Y|Jingle|he|imerscmidt|19901002|123456789|3') 
,('May 1st, 2015|N|Jingleheimerscmidt|19901002|123456789|3') 
,('May 5th, 2015|Y|Jon|19901001||1') 
,('May 1st, 2015|N|Jon|19901002||1') 
,('May 1st, 2015|Y|Jacob|19901001|234567890|2') 
,('May 5th, 2015|N|Jingleheimerscmidt|19901001|123456789|3') 
,('May 1st, 2015|Y|Jingleheimerscmidt|19901001|123456789|3') 

;WITH cteFakePrimaryKey AS (
    SELECT 
     LumpedColumns 
     ,CASE WHEN LEN(LumpedColumns) - LEN(REPLACE(LumpedColumns,'|','')) > 5 THEN 
      LEN(LumpedColumns) - LEN(REPLACE(LumpedColumns,'|','')) - 5 ELSE 0 END as MergeXPositions 
     ,ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as PK 
    FROM 
     @CSV 
) 


, cteRecursive AS (
    SELECT 
     PK 
     ,LumpedColumns 
     ,MergeXPositions 
     ,LEFT(LumpedColumns,CHARINDEX('|',LumpedColumns)-1) as ColValue 
     ,RIGHT(LumpedColumns,LEN(LumpedColumns) - CHARINDEX('|',LumpedColumns)) as Remaining 
     ,1 As OrdinalPosition 
    FROM 
     cteFakePrimaryKey 

    UNION ALL 

    SELECT 
     PK 
     ,LumpedColumns 
     ,MergeXPositions 
     ,LEFT(Remaining,CHARINDEX('|',Remaining)-1) 
     ,RIGHT(Remaining,LEN(Remaining) - CHARINDEX('|',Remaining)) 
     ,OrdinalPosition + 1 
    FROM 
     cteRecursive 
    WHERE 
     Remaining IS NOT NULL AND CHARINDEX('|',Remaining) > 0 

    UNION ALL 

    SELECT 
     PK 
     ,LumpedColumns 
     ,MergeXPositions 
     ,Remaining 
     ,NULL 
     ,OrdinalPosition + 1 
    FROM 
     cteRecursive 
    WHERE Remaining IS NOT NULL AND CHARINDEX('|',Remaining) = 0 
) 

, cteOrdinalGroup AS (
    SELECT 
     PK 
     ,LumpedColumns 
     ,ColValue 
     ,OrdinalPosition 
     ,DENSE_RANK() OVER (PARTITION BY PK ORDER BY 
      CASE 
      WHEN OrdinalPosition < 3 THEN OrdinalPosition 
      WHEN OrdinalPosition > (3 + MergeXPositions) THEN OrdinalPosition 
      ELSE 3 END) as OrdinalGRoup 

    FROM 
     cteRecursive 
) 

SELECT 
    PK 
    ,LumpedColumns 
    ,MAX(CASE WHEN OrdinalGRoup = 1 THEN ColValue END) as Date_Added 
    ,MAX(CASE WHEN OrdinalGRoup = 2 THEN ColValue END) as this_flag 
    ,STUFF(
     (SELECT '|' + ColValue 
     FROM 
      cteOrdinalGroup g2 
     WHERE 
      g1.PK = g2.PK 
      AND g2.OrdinalGroup = 3 
     ORDER BY 
      g2.OrdinalPosition 
     FOR XML PATH('')) 
     ,1,1,'') as name 
    ,MAX(CASE WHEN OrdinalGRoup = 4 THEN ColValue END) as DOB 
    ,MAX(CASE WHEN OrdinalGRoup = 5 THEN ColValue END) as SSN 
    ,MAX(CASE WHEN OrdinalGRoup = 6 THEN ColValue END) as ID 
FROM 
    cteOrdinalGroup g1 
GROUP BY 
    PK 
    ,LumpedColumns 
ORDER BY 
    PK 
0

그건 당신이 처리 할 필요가 하나의 사건하고 파일을 수정하지 않고 당신이 인포매티카, 당신은 CommandFile에서이 Source Qualifier에 대한 Input Type 세션 속성을 변경할 수 있습니다 할 필요가있는 경우 및 다음과 같이 대체 할 sed를 사용하십시오.

cat $$FileName | sed -e 's/Jingle|heimerscmidt/Jingleheimerscmidt/g' 

따라서 멋진 솔루션이 아니므로 일반적인 것은 아닙니다. 그러나 아마도 이것은 당신에게 어떤 아이디어를 제공하거나 줄 것입니다.