2009-06-22 3 views
6

어떻게 이런 일이 발생하는지 파악할 수 없습니다. 몇 가지 이유 만,FIRSTROW 매개 변수가있는 SQL 대량 삽입은 다음 줄을 건너 뜁니다.

BULK INSERT sometable 
FROM 'E:\filefromabove.txt 
WITH 
(
FIRSTROW = 2, 
FIELDTERMINATOR= '|', 
ROWTERMINATOR = '\n' 
) 

그러나 :

***A NICE HEADER HERE*** 
00000|SSNV|00013893-03JUN09 
0000005678|ABCD|00013893-03JUN09 
0000009112|0000|00013893-03JUN09 
0000009112|0000|00013893-03JUN09 

가 여기 내 대량 삽입 문의 : 여기

내가 SQL 서버에 대량 삽입 2005을 시도하고있어 파일의 예 내가 얻을 수있는 출력은 다음과 같습니다.

0000005678|ABCD|00013893-03JUN09 
0000009112|0000|00013893-03JUN09 
0000009112|0000|00013893-03JUN09 

헤더를 제거하지 않으면 첫 번째 레코드가 항상 건너 뜁니다. 모두 FIRSTROW 매개 변수를 사용하지 마십시오. 이것이 어떻게 가능한지?

미리 감사드립니다.

답변

12

BULK INSERT/BCP으로 다른 형식으로 행을 건너 뛸 수 있다고 생각하지 않습니다. 나는이 실행하면

는 :

TRUNCATE TABLE so1029384 

BULK INSERT so1029384 
FROM 'C:\Data\test\so1029384.txt' 
WITH 
(
--FIRSTROW = 2, 
FIELDTERMINATOR= '|', 
ROWTERMINATOR = '\n' 
) 

SELECT * FROM so1029384 

를 내가 얻을 : 그것은 필요처럼

col1            col2            col3 
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- 
***A NICE HEADER HERE*** 
00000SSNV            00013893-03JUN09 
0000005678           ABCD            00013893-03JUN09 
0000009112           0000            00013893-03JUN09 
0000009112           0000            00013893-03JUN09 

그것은 보이는 '|' 첫 번째 열로 새 행을 읽어 들이기 때문에 헤더 데이터에서도 마찬가지입니다. 분명히 필드 종결 자 매개 변수를 포함하면 모든 행이 이어야하며에는 하나가 있어야합니다.

사전 처리 단계로 행을 제거 할 수 있습니다. 또 다른 가능성은 전체 행만 선택하여 처리하는 것입니다 (헤더 제외). SSIS처럼 이것을 처리 할 수있는 도구를 사용하십시오.

+0

당신이 정확합니다! '||'를 추가하면 헤더의 끝에, 그것은 잘 작동합니다. 삽입 할 각 파일에서 헤더를 제거하려고 시도 할 것입니다. 감사! – gibbo

6

헤더가 실제 데이터 행과 동일한 줄 끝을 사용하고 있는지 확인하십시오 (ROWTERMINATOR에 지정된대로)?

업데이트 : FIRSTROW 특성은 열 머리글을 건너 뛸 을위한 것이 아닙니다

: MSDN에서. 헤더를 건너 뛰는 것은 BULK INSERT 문에서 지원되지 않습니다. 행을 건너 뛸 때 SQL Server 데이터베이스 엔진은 필드 종결 자에서만 을보고 은 건너 뛴 행의 필드의 데이터에 대한 유효성을 검사하지 않습니다.

+0

안녕하세요, 불행히도 행마다 CRLF가 있습니다. 그래도 의견을 보내 주셔서 감사합니다. – gibbo

4

전체 행을 한 열로 읽은 다음 XML을 사용하여 데이터를 구문 분석하는 것이 가장 쉬운 방법입니다. 일부 데이터는 BCP 비 SQL 데이터 소스에서 SQL 서버로 가져 오기 돌볼 수있는 방법을 난도질을 감안할 때

IF (OBJECT_ID('tempdb..#data') IS NOT NULL) DROP TABLE #data 
CREATE TABLE #data (data VARCHAR(MAX)) 

BULK INSERT #data FROM 'E:\filefromabove.txt' WITH (FIRSTROW = 2, ROWTERMINATOR = '\n') 

IF (OBJECT_ID('tempdb..#dataXml') IS NOT NULL) DROP TABLE #dataXml 
CREATE TABLE #dataXml (ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED, data XML) 

INSERT #dataXml (data) 
SELECT CAST('<r><d>' + REPLACE(data, '|', '</d><d>') + '</d></r>' AS XML) 
FROM #data 

SELECT d.data.value('(/r//d)[1]', 'varchar(max)') AS col1, 
     d.data.value('(/r//d)[2]', 'varchar(max)') AS col2, 
     d.data.value('(/r//d)[3]', 'varchar(max)') AS col3 
FROM #dataXml d 
+0

SSIS를 피하는 놀라운 스크립트입니다. 첫 번째 행만 가져오고 대상 행과 일치하는지 확인한 다음 헤더를 제외한 모든 데이터를 가져옵니다. 감사! – lwall

-1

, 내가 먼저 약간의 스크래치 테이블에 모든 BCP 가져 오기를하고 건의 할 것입니다.예를 들어

테이블 잘라 내기 Address_Import_tbl

BULK는 FROM dbo.Address_Import_tbl 를 삽입 'E : \ 외부 \ SomeDataSource \ Address.csv' ( FIELDTERMINATOR = WITH '|', ROWTERMINATOR = '\ n ', MAXERRORS = 10 )

Address_Import_tbl의 모든 열이 가능한 한 불가지론스럽고 형식 변환 오류가 발생하지 않도록 nvarchar()인지 확인하십시오.

그런 다음 Address_Import_tbl에 필요한 수정 사항을 적용하십시오. 원하지 않는 헤더를 삭제하는 것과 같습니다.

그런 다음 INSERT SELECT 쿼리를 실행하여 필요한 모든 데이터 유형 변환과 함께 Address_Import_tbl에서 Address_tbl로 복사하십시오. 예를 들어, 가져온 날짜를 SQL DATETIME으로 변환합니다.

관련 문제