2

我有一個包含6百萬行的CSV文件。每行都由相同的格式組成,例如/使用BULK INSERT來映射列

I,h,q,q,3,A,5,Q,3,[,5,Q,8,c,3,N,3,E,4,F,4,g,4,I,V,9000,0000001-100,G9999999990001800000000000001,G9999999990000001100PDNELKKMMCNELRQNWJ010, , , , , , ,D,Z 

我在表中有2列。

第一列應該是CSV中的字段27,第二列應該是CSV文件中的整行。

我試圖設置一個格式文件,但無法讓它工作。

它甚至有可能做這種映射?

以下是我有:

BULK INSERT Staging FROM 'C:\Data.txt' 
    WITH 
    (
     FIELDTERMINATOR =',', 
     ROWTERMINATOR ='\n', 
     KEEPNULLS, 
     formatfile='C:\format.fmt' 
    ) 

這是我的格式文件

9.0 
2 
1  SQLCHAR  0  40  ","  27  Col27    SQL_Latin1_General_CP1_CI_AS 
2  SQLCHAR  0  200  "\r\n" 1  Col1    SQL_Latin1_General_CP1_CI_AS 

相比較而言,我在SQLite的這個工作這需要2分鐘35secs。

+0

這可能嗎?是。也許你可以包括你的嘗試,有人可能會發現問題。 –

+0

@TomH。問題已更新 – Jon

+0

現在我明白你想要做什麼了,我認爲你必須使用臨時表,正如Chris Townsend所建議的那樣。 –

回答

4

你可以破解這個螺母一對夫婦的方式,但我確實是批量插入整個CSV文件導入通過動態SQL臨時表的方式:

CREATE TABLE #BulkLoadData(
    RecordData NVARCHAR(max) 
) 


SET @SQL = 'BULK INSERT #BulkLoadData FROM ''' + @SourceFileFullPath + ''' ' 
SET @SQL = @SQL + 'WITH (FORMATFILE = ''' + @UPXInputFileBulkLoadFormat + 'UPXInputFileBulkLoadFormat.xml'', TABLOCK, ROWS_PER_BATCH = 2500) ' 

EXECUTE (@SQL) 

然後你就可以將數據插入到該目標表是這樣的:

INSERT INTO dbo.TargetTable 
SELECT dbo.fnParseString(27, ',', RecordData), RecordData 

你需要創建一個解析函數,像這樣:

CREATE FUNCTION [dbo].[fnParseString] 
(
    @Section SMALLINT, 
    @Delimiter CHAR, 
    @Text VARCHAR(MAX) 
) 
RETURNS VARCHAR(8000) 
AS 

BEGIN 
DECLARE @startindex NUMERIC(18,0), 
    @length NUMERIC(18,0), 
    @FieldPosition INT 

SET @FieldPosition = ABS(@Section) - 1 
SET @startindex = 0 


WHILE @FieldPosition != 0 
BEGIN 
    SET @FieldPosition = @FieldPosition - 1 
    SET @startindex = CHARINDEX(@Delimiter, @Text, @startindex + 1) 
END  


SET @Text = SUBSTRING(@Text, @startindex + 1, LEN(@Text) - @startindex) 
SET @Text = SUBSTRING(@Text, 0, CHARINDEX(@Delimiter, @Text)) 

RETURN @Text 
END 

希望有所幫助!如果你需要格式文件的幫助,請告訴我。

這裏是格式文件的內容:

<?xml version="1.0"?> 
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <RECORD> 
    <FIELD ID="1" xsi:type="CharTerm" TERMINATOR="\n" MAX_LENGTH="8000" COLLATION="SQL_Latin1_General_CP1_CI_AS"/> 
    </RECORD> 
    <ROW> 
    <COLUMN SOURCE="1" NAME="RecordData" xsi:type="SQLVARYCHAR"/> 
    </ROW> 
</BCPFORMAT> 
+0

認爲我將需要格式文件的幫助,因爲整行將成爲一列。我發佈了我的格式文件,但不確定整行列是否正確。我曾考慮過這種方法,但認爲插入/更新包含子集的表的時間過於昂貴 – Jon

+0

您也可以將一列(RecordData)直接批量插入到目標表中,然後運行更新填充「其他」列。 –

+0

我剛剛將大容量插入到登臺表中,並且花費了比SQLite更長的時間。是對的嗎? – Jon