2012-04-01 117 views
0

我使用SQL Server 2008並有一個包含5個字符類型列的表。SQL Server BULK INSERT固定長度字符數據

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插入該文件。我希望BULK INSERT在沒有這些字段時插入空值,如果工具到達行尾,只爲其餘字段插入空值。

回答

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]也可把順序等同於訂單最初在文件中,你可能不需要它,但恕我直言,開銷是微乎其微的,而且MSSQL對HEAP表無論如何都不太熱衷,所以它有「好東西[Tm]」

+0

如果這是唯一的解決方案可用,哪種方式可以更高效,使用sql server來解析這些char值或編寫一個c#windows應用程序並將它解析(從文件逐行讀取,解析和插入行)。我試圖總結一下情況,實際上,目標表有35列,最後6列可能是空的。數據文件有60行數據。每5分鐘我會有一個新的數據文件。 – 2012-04-02 18:52:37

+0

這似乎是唯一的解決方案,選擇這種方式,謝謝.. – 2012-04-03 10:59:28

+0

如果你只需要像60行數據我不會太擔心性能。雖然SQL在字符串操作(什麼語言是?)方面可能不太好,但它在IMHO中做得不錯。寫35列的聲明不會很有趣,雖然= P – deroby 2012-04-03 12:55:08