2012-03-20 153 views
2

我已經從Maxmind下載GeoLiteCountry CSV文件 - http://www.maxmind.com/app/geolitecountry。使用給我的格式作爲標準(以便這可以成爲一個自動化的任務),我試圖將所有的數據導入到一個表中。將Maxmind CSV導入到SQL Server中

我創建了一個新的表提供IPCountries2具有精確匹配的列列:

FromIP  varchar(50), 
ToIP   varchar(50), 
BeginNum  bigint, 
EndNum  bigint, 
CountryCode varchar(50), 
CountryName varchar(250) 

使用的代碼,我能找到的各種塊,我無法得到它的工作使用字段終止符和行終止:

BULK 
INSERT CSVTest 
FROM 'c:\csvtest.txt' 
WITH 
(
    FIELDTERMINATOR = '","', 
    ROWTERMINATOR = '\n' 
) 
GO 

這樣做的結果是單行插入,正確的除了最後一個曾與下一行溢出(大概是整個數據庫,如果我沒有限制)。另外,第一個單元在開始時有一個報價。

我環顧四周,發現一種稱爲格式文件(從未使用過這些文件)。製作一個看起來像:

10.0 
6 
1 SQLCHAR  0 50 "," 1 FromIP  "" 
2 SQLCHAR  0 50 "," 2 ToIP  "" 
3 SQLBIGINT 0 19 "," 3 BeginNum "" 
4 SQLBIGINT 0 19 "," 4 EndNum  "" 
5 SQLCHAR  0 50 "," 5 CountryCode "" 
6 SQLCHAR  0 250 "\n" 6 CountryName "" 

但對BIGINT線這樣的錯誤:

消息4867,級別16,狀態1,行1
爲行批量加載數據轉換錯誤(溢出) 1,第3列(BeginNum)。

它做了10次,然後停止因爲最大錯誤計數。

我能夠得到第一個方法,如果我把它放入Excel並重新保存,這將刪除引號。但是,我不想依賴這種方法,因爲我希望這個方法每週自動更新一次,而不必手動打開並重新保存。

我不介意我最終使用的兩種方法中的哪一種,只要它使用乾淨的文件。我看了他們的文檔,但他們只有PHP或MS Access的代碼。

編輯

從CSV文件中的一些行:

"1.0.0.0","1.0.0.255","16777216","16777471","AU","Australia" 
"1.0.1.0","1.0.3.255","16777472","16778239","CN","China" 
"1.0.4.0","1.0.7.255","16778240","16779263","AU","Australia" 
"1.0.8.0","1.0.15.255","16779264","16781311","CN","China" 
"1.0.16.0","1.0.31.255","16781312","16785407","JP","Japan" 
"1.0.32.0","1.0.63.255","16785408","16793599","CN","China" 
"1.0.64.0","1.0.127.255","16793600","16809983","JP","Japan" 
"1.0.128.0","1.0.255.255","16809984","16842751","TH","Thailand" 
"1.1.0.0","1.1.0.255","16842752","16843007","CN","China" 
"1.1.1.0","1.1.1.255","16843008","16843263","AU","Australia" 
"1.1.2.0","1.1.63.255","16843264","16859135","CN","China" 
"1.1.64.0","1.1.127.255","16859136","16875519","JP","Japan" 
"1.1.128.0","1.1.255.255","16875520","16908287","TH","Thailand" 

更新

經過一段持續存在的,我能夠把事情的工作95%,與原來的方法(不格式文件)。然而,微微一變,看起來像這樣:

BULK INSERT IPCountries2 
FROM 'c:\Temp\GeoIPCountryWhois.csv' 
WITH 
(
    FIELDTERMINATOR = '","', 
    ROWTERMINATOR = '"' 
) 
GO 

一切順利在正確的領域,因爲他們應該,我唯一的問題是,在第一列有在一開始的報價。一些示例數據:

FromIP ToIP BeginNum EndNum CountryCode Country 
"2.21.248.0 2.21.253.255 34994176 34995711 FR France 
"2.21.254.0 2.21.254.255 34995712 34995967 EU Europe 
"2.21.255.0 2.21.255.255 34995968 34996223 NL Netherlands 
+0

您可以發佈CSV文件的前幾行數據嗎? – datagod 2012-03-20 16:42:56

+0

啊是我多麼愚蠢,在我的OP中找到 – Chris 2012-03-20 16:45:35

+0

在你的原始批量插入中,你指定FIELDTERMINATOR爲'「,」'。爲什麼逗號周圍有雙引號? – datagod 2012-03-20 16:48:25

回答

2

成功。 Searching aroundanother forum的一些幫助終於讓我看到了我的解決方案。對於那些需要類似解決方案的人,請繼續閱讀:

我結束了使用格式文件方法 - 是否可以使用fieldterminators和行終止符我不確定。

我的SQL代碼如下所示:

CREATE TABLE #TempTable 
(
    DuffColumn varchar(50), 
    FromIP  varchar(50), 
    ToIP  varchar(50), 
    BeginNum bigint, 
    EndNum  bigint, 
    CountryCode varchar(50), 
    CountryName varchar(250) 
) 

BULK 
INSERT #TempTable 
FROM 'c:\Temp\GeoIPCountryWhois.csv' 
WITH 
(
    FORMATFILE = 'C:\Temp\format.fmt' 
) 

INSERT INTO IPCountries2 (FromIP, ToIP, BeginNum, EndNum, CountryCode, Country) 
    SELECT FromIP, ToIP, BeginNum, EndNum, CountryCode, CountryName FROM #TempTable 

正如我在調研中發現,有必要擁有它只是捕獲的第一個引號一個無用的列。

我的格式文件看起來像:

10.0 
7 
1 SQLCHAR  0 1 ""  1 DuffColumn "" 
2 SQLCHAR  0 50 "\",\"" 2 FromIP  "" 
3 SQLCHAR  0 50 "\",\"" 3 ToIP  "" 
4 SQLCHAR  0 19 "\",\"" 4 BeginNum "" 
5 SQLCHAR  0 19 "\",\"" 5 EndNum  "" 
6 SQLCHAR  0 50 "\",\"" 6 CountryCode "" 
7 SQLCHAR  0 250 "\"\n" 7 CountryName "" 

要注意,儘管最終被存儲爲BIGINT,BeginNum和EndNum都傳過來SQLCHARS,否則插不上號奇數乘(某事關於讀取它作爲字節而不是數字,我沒有完全理解它)。

就是這樣。完全自動完成此腳本的最後一件事是首先截斷表以清除舊記錄。但是,這可能不是每個人的需要。

0

試試這個命令。我所做的一切是從FIELDTERMINATOR刪除雙引號:

BULK 
INSERT CSVTest 
FROM 'c:\csvtest.txt' 
WITH 
(
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
) 
GO 

你的數據字段實際上是由逗號結束,而不是逗號用引號引用。我還建議建立一個臨時/導入表完全符合您的源文件中的數據類型,在這種情況下看起來像:

FromIP  varchar(50), 
ToIP   varchar(50), 
BeginNum  varchar(50), 
EndNum  varchar(50), 
CountryCode varchar(50), 
CountryName varchar(250) 

爲BeginNum和EndNum源數據實際上是字符串,而不是BIGINT。您可以在將數據導入暫存表後將其轉換。

+0

請看我對OP的評論,可悲的是這並沒有幫助 – Chris 2012-03-20 16:55:21

-1
declare @sql varchar(1000) 
declare @filename varchar(100) = 'C:\Temp\GeoIPCountryWhois.csv' 

set @sql = 
'BULK INSERT geoip FROM ''' + @filename + ''' 
WITH 
(
CHECK_CONSTRAINTS, 
FIELDTERMINATOR = '','', 
ROWTERMINATOR = ''' + char(0x0A) + ''' 
)' 
exec (@sql)