2012-04-01 4 views
0

SQL Server 2008을 사용하고 5 개의 입력 된 열이있는 테이블이 있습니다.SQL Server 대량 고정 길이 고정 문자 데이터

CREATE TABLE [dbo].[deviceDataBulk](
[f1] [char](9) NULL, 
[f2] [char](5) NULL, 
[f3] [char](7) NULL, 
[f4] [char](7) NULL, 
[f5] [char](6) NULL) 

또한 bcp 형식 파일이 있습니다.

<RECORD> 
<FIELD ID="1" xsi:type="CharFixed" LENGTH="9" COLLATION="Turkish_CI_AS"/> 
<FIELD ID="2" xsi:type="CharFixed" LENGTH="5" COLLATION="Turkish_CI_AS"/> 
<FIELD ID="3" xsi:type="CharFixed" LENGTH="7" COLLATION="Turkish_CI_AS"/> 
<FIELD ID="4" xsi:type="CharFixed" LENGTH="7" COLLATION="Turkish_CI_AS"/> 
<FIELD ID="5" xsi:type="CharFixed" LENGTH="6" COLLATION="Turkish_CI_AS"/> 
</RECORD> 
<ROW> 
<COLUMN SOURCE="1" NAME="f1" NULLABLE="YES" xsi:type="SQLCHAR"/> 
<COLUMN SOURCE="2" NAME="f2" NULLABLE="YES" xsi:type="SQLCHAR"/> 
<COLUMN SOURCE="3" NAME="f3" NULLABLE="YES" xsi:type="SQLCHAR"/> 
<COLUMN SOURCE="4" NAME="f4" NULLABLE="YES" xsi:type="SQLCHAR"/> 
<COLUMN SOURCE="5" NAME="f5" NULLABLE="YES" xsi:type="SQLCHAR"/> 
</ROW> 

내 데이터 파일에는 각 줄에 필드 종결자가없는 고정 길이 char 데이터가 들어 있습니다. 따라서 전체 줄은 34 자입니다.

제 문제는 필드 4이며 필드 5는 각 행에 없을 수 있습니다. 나는 그 파일에 21 줄의 긴 줄 또는 28 줄의 긴 줄을 가질 수 있습니다.

필드 5가 존재하고 필드 4가없는 경우는 없습니다.

텍스트 파일의 가능한 시나리오는 다음과 같습니다.

f1 f2 f3 f4 f5 
f1 f2 f3 f4 
f1 f2 f3 

BULK INSERT과 함께이 파일을 삽입 할 수 없습니다. 해당 필드가 없을 때 null을 삽입하려면 BULK INSERT을 원하고, 도구가 줄 끝까지 도달하면 나머지 필드는 null을 삽입하면됩니다.

답변

0

2 단계 접근 방법은 어떻습니까? 먼저 데이터를 '큰 행'으로 스테이징 테이블에로드 한 다음 두 번째 쿼리를 사용하여 원시 행을 해당 필드로 분할하고 '누락 된 f5 및/또는 f4 열'위치를 처리합니다.

은 다음과 같이 (다소)를 보일 것이다 (안된!)

CREATE TABLE [dbo].[deviceDataBulk_staging](
[rowid] int IDENTITY(1 , 1) PRIMARY KEY, 
[raw] [varchar](34) NOT NULL) 

GO 
BULK INSERT [deviceDataBulk_staging] 
FROM '<your file>' 
-- not sure if you really need a format-file here, 
-- simply make sure to pass the correct line-separator if it is 'exotic'. 

GO 

INSERT [deviceDataBulk] (f1, f2, f3, f4, f5) 
SELECT f1 = SubString([raw], 1 , 9), 
     f1 = SubString([raw], 10 , 5), 
     f1 = SubString([raw], 15 , 7), 
     f1 = (CASE WHEN Length([raw] < 22 THEN NULL ELSE SubString([raw], 22 , 7) END), 
     f1 = (CASE WHEN Length([raw] < 29 THEN NULL ELSE SubString([raw], 29 , 6) END) 
    FROM [deviceDataBulk_staging] 
ORDER BY [rowid] 

준비 파일은 다음 보일 것 같은 :

에서 [ROWID]가 동일한 순서를 유지하기가 원래 파일의 순서 일 필요는 없지만 IMHO 오버 헤드가 최소화되고 MSSQL이 HEAP 테이블에 너무 열중하지 않아 "좋은 점 [Tm]"

+0

유일한 해결책 인 경우 사용할 수있는 방법은 SQL Server를 사용하여 이러한 char 값을 파싱하거나 C#을 윈도우 응용 프로그램과 leting 파싱 (파일에서 줄 단위로 읽기, 구문 분석 및 행 삽입) 않습니다. 나는 상황을 요약하려고 노력했다. 사실 목표 테이블에는 35 개의 열이 있고 마지막 6 개의 테이블은 비어있을 수있다. 그리고 데이터 파일에는 60 줄의 데이터가 있습니다. 나는 5 분마다 새로운 데이터 파일을 갖게 될 것이다. –

+0

이 방법을 선택하는 유일한 해결책 인 것 같습니다. –

+0

60 줄의 데이터 만 필요하면 성능에 대해 너무 걱정하지 않아도됩니다. SQL이 문자열 조작 (언어는 무엇입니까?)에 좋지 않을 수도 있지만, IMHO는 괜찮은 작업을 수행합니다. 35 열에 대한 문장을 작성하는 것은 재미 없을 것입니다. = P – deroby

관련 문제