Импорт Maxmind CSV в SQL Server - PullRequest
       14

Импорт Maxmind CSV в SQL Server

2 голосов
/ 20 марта 2012

Я скачал файл GeoLiteCountry CSV из Maxmind - http://www.maxmind.com/app/geolitecountry. Используя стандартный формат, предоставленный мне (чтобы это могло стать автоматизированной задачей), я пытаюсь импортировать все данные в таблицу.

Я создал новую таблицу 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

Ответы [ 4 ]

2 голосов
/ 26 марта 2012

Успех. Поиск вокруг и некоторая помощь от другого форума наконец-то добрались до моего решения. Для тех, кто нуждается в подобном решении, продолжайте читать:

Я закончил тем, что использовал метод форматирования файла - возможно ли использовать терминаторы полей и терминаторы строк, я не уверен.

Мой код 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, в противном случае вставка выполняет нечетное умножение чисел (что-то о чтении их как байтов, а не цифр, я не совсем понять это).

И это все. Последнее, что должно полностью автоматизировать этот сценарий, - это сначала обрезать таблицу, чтобы очистить старые записи. Однако это может быть не всем нужно.

1 голос
/ 01 ноября 2013

Я только что использовал эту статью, http://www.webstein.net/blog/importing-maxmind-ip-database-into-sql-server.

СОВЕРШЕНО за 7 минут !!

ОГРОМНОЕ СПАСИБО Раулю.

Это избавило меня от многих мучений, связанных с другими статьями о том, как импортировать такие файлы.

Единственное, что я сделал, это удалил первую строку из обоих файлов. Я использовал Notepad ++, и он тоже сделал свою работу.

0 голосов
/ 30 мая 2014
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)
0 голосов
/ 20 марта 2012

Попробуйте эту команду. Все, что я сделал, это удалил двойные кавычки из вашего 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. Вы можете преобразовать эти данные, как только они будут импортированы в промежуточную таблицу.

...