2012-10-25 60 views
2

我從客戶端獲取CSV,我需要將該文件導入數據庫。我經歷了無數的迭代,是無限的解決方案測試的一部分。我需要完整解決方案時遇到問題。我想要批量插入CSV

CSV有14個字段,tempdb數據庫有15個字段(最後一個是標識列)。數據到達時沒有標識,我需要根據db設計的行唯一編號。

我模糊了顯示的測試數據,但它模仿了數據正常。

T2012-DAT;09-01-2012;09-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5 
T2012-DAT;10-01-2012;10-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5 
T2012-DAT;11-01-2012;11-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5 
T2012-DAT;12-01-2012;12-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5 
T2012-DAT;13-01-2012;13-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7 
T2012-DAT;16-01-2012;16-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5

我在tempdb中創建的臨時表。你會注意到它有15個字段,最後一個是所需的身份。

CREATE TABLE BudgetImport(
    sBudgetName varchar(20) COLLATE Danish_Norwegian_CI_AS 
    , dStartDate varchar(12) COLLATE Danish_Norwegian_CI_AS 
    , dEndDate varchar(12) COLLATE Danish_Norwegian_CI_AS 
    , prCode int 
    , decTotal varchar(20) COLLATE Danish_Norwegian_CI_AS 
    , sRefTimeTypeID varchar(10) COLLATE Danish_Norwegian_CI_AS 
    , sRefEmployeeID varchar(10) COLLATE Danish_Norwegian_CI_AS 
    , decHours varchar(20) COLLATE Danish_Norwegian_CI_AS 
    , decRate varchar(20) COLLATE Danish_Norwegian_CI_AS 
    , sDepartmentID varchar(10) COLLATE Danish_Norwegian_CI_AS NULL 
    , sCentre varchar(10) COLLATE Danish_Norwegian_CI_AS NULL 
    , sPurpose varchar(10) COLLATE Danish_Norwegian_CI_AS NULL 
    , sProjectID varchar(10) COLLATE Danish_Norwegian_CI_AS NULL 
    , decNormHours varchar(20) COLLATE Danish_Norwegian_CI_AS 
    --, iRowNumber int identity(500000,1) 
)

GO

 
-- import data by csv 
BULK INSERT BudgetImport 
FROM 'D:\budgetposter.csv' 
WITH 
(
    fieldterminator = ';' 
    , rowterminator = '\r\n' 
    , codepage = '1252' 
)

當我包含在產品的身份我得到這個錯誤:

Msg 4866, Level 16, State 1, Line 3 
The bulk load failed. The column is too long in the data file for row 1, column 15. Verify that the field terminator and row terminator are specified correctly.

如果我排除,錯誤修改:

Msg 4866, Level 16, State 1, Line 3 
The bulk load failed. The column is too long in the data file for row 1, column 14. Verify that the field terminator and row terminator are specified correctly.

如果我更改了rowterminator = '\n'它來自,但我錯過了身份。

如果我再包含在產品的誤差變身份:

Msg 4864, Level 16, State 1, Line 3 
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 1, column 15 (iRowNumber).

當我測試我不包括INSERT INTO dbo."the-real-datatable",只是做單獨SELECT FROM BudgetImport。因此我避免將另外16000行插入真正的數據表中。

如果您注意並瞭解匈牙利語符號,您會注意到我正在使用varchars,即使datatime或decimal可能是正確的形式。經過大約4-6小時的測試後,我正在做這件事,並且無休止地提供頭痛和頭髮脫落。 Varchar是KISS解決方案,後來我做了CONVERT()

我的整個問題都會解決該行的最後一個字段。 - 我試過添加1和2;在decNormHours之後,我嘗試添加空值(;;或; 1;或; n;)。 - 我試過formatfile.xml - 再也沒有蛋糕。沒有格式文件的情況下,我獲得了更多的成功。 - 我已經嘗試改爲英國數字符號。 = DK符號更成功。 - 我試過每一個我可以想出來的技巧都無濟於事。

是的,CSV中沒有標識字段,沒關係。您只需使用我在表格創建中描述的默認自動identity(500000,1)。哦,500000是我現在達到的大約一排ID,隨着時間的推移它會增加。

請問我需要做什麼才能使這個好?

編輯:
使用格式文件

 
$lt;? xml version="1.0 " ? $gt; 
$lt;BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"$gt; 
$lt;RECORD$gt; 
    FIELD ID="1" xsi:type="NCharTerm" TERMINATOR=";" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ 
    FIELD ID="2" xsi:type="CharFixed" LENGTH="9" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ 
    FIELD ID="3" xsi:type="CharFixed" LENGTH="9" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ 
    FIELD ID="4" xsi:type="NCharTerm" TERMINATOR=";"/ 
    FIELD ID="5" xsi:type="NCharTerm" TERMINATOR=";"/ 
    FIELD ID="6" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ 
    FIELD ID="7" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ 
    FIELD ID="8" xsi:type="NCharTerm" TERMINATOR=";"/ 
    FIELD ID="9" xsi:type="NCharTerm" TERMINATOR=";"/ 
    FIELD ID="10" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ 
    FIELD ID="11" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ 
    FIELD ID="12" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ 
    FIELD ID="13" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ 
    FIELD ID="14" xsi:type="NCharTerm" TERMINATOR=";"/ 
/RECORD 
ROW 
    COLUMN SOURCE="1" NAME="sBudgetName" xsi:type="SQLNVARCHAR" LENGTH="20"/
    COLUMN SOURCE="2" NAME="dStartDate" xsi:type="SQLDATETIME"/ 
    COLUMN SOURCE="3" NAME="dEndDate" xsi:type="SQLDATETIME"/ 
    COLUMN SOURCE="4" NAME="prCode" xsi:type="SQLSMALLINT"/ 
    COLUMN SOURCE="5" NAME="decTotal" xsi:type="SQLDECIMAL"/ 
    COLUMN SOURCE="6" NAME="sRefTimeTypeID" xsi:type="SQLNVARCHAR" LENGTH="10"/ 
    COLUMN SOURCE="7" NAME="sRefEmployeeID" xsi:type="SQLNVARCHAR" LENGTH="10"/ 
    COLUMN SOURCE="8" NAME="decHours" xsi:type="SQLDECIMAL"/ 
    COLUMN SOURCE="9" NAME="decRate" xsi:type="SQLDECIMAL"/ 
    COLUMN SOURCE="10" NAME="sDepartmentID" xsi:type="SQLNVARCHAR" LENGTH="10"/ 
    COLUMN SOURCE="11" NAME="Centre" xsi:type="SQLNVARCHAR" LENGTH="10"/ 
    COLUMN SOURCE="12" NAME="Purpose" xsi:type="SQLNVARCHAR" LENGTH="10"/ 
    COLUMN SOURCE="13" NAME="sRefProjectID" xsi:type="SQLNVARCHAR" LENGTH="10"/ 
    COLUMN SOURCE="14" NAME="decNormHours" xsi:type="SQLDECIMAL"/ 
/ROW 

放我回去做第一場順利實施。因此,爲了爭取最終細節的正確性,我最終爭取讓它在第一位工作/做任何事情。 錯誤:

 
Msg 4863, Level 16, State 1, Line 3 
Bulk load data conversion error (truncation) for row 1, column 1 (sBudgetName). 

注:hmm似乎SO不喜歡xml。多麼奇怪。

+0

你提到了各種各樣的東西不工作,但你還沒有說過,如果你已經按照說明(http://msdn.microsoft.com/en-us/library/ms179250.aspx)跳過表格列使用fo rmat文件?和[這個問題](http://stackoverflow.com/questions/8347254/bcp-import-error-with-xml-format-file-and-identity-column)非常密切地描述你的情況,如果不完全。 – Pondlife

+0

使用格式文件,讓我回到第一列的戰鬥。只是一個更新問題的問題。 – DoStuffZ

回答

0

這是一個比解決方案更多的解決方法,但由於您面對的是列數問題,爲什麼不在之後添加索引列?

你可以做這樣的事情:

  • 具有相同的列數

然後導入您的CSV到您的臨時表,

ALTER TABLE BudgetImport 
    ADD Id INTEGER 
GO 

WITH Cte 
AS 
(
    SELECT * 
    , ROW_NUMBER() OVER(ORDER BY [**column of your choice**] DESC) AS RowNumber 
    FROM BudgetImport 
) 
UPDATE Cte 
SET Id = RowNumber 
GO 

ALTER TABLE BudgetImport 
ALTER COLUMN Id INTEGER NOT NULL 
GO 

ALTER TABLE BudgetImport 
ADD PRIMARY KEY (Id) 
GO 
+0

是的,問題是我有一個包括身份的解決方案。我仍然相信我可以擁有蛋糕,也可以吃。否則這將是最終的解決方案。不用擔心編號與排序,預算編號將在每次導入前被刪除。 – DoStuffZ

+0

雖然我確實認爲這是正確的解決方案,但我無法按照自己的意願去做。其他人應該及時看待這個問題,並且做你應該做的事情。我不得不想出另一個解決方案。感謝您的協助。 – DoStuffZ