2013-08-03 3 views
2

나는 MySQL 5.6을 사용하여 INET6_ATONIS_IPV6과 같은 새로운 기능을 실험하고 있습니다. 스크립트가 IPV4을 읽으면 데이터를 테이블에 완벽하게 삽입합니다. 그러나 IPv6의 경우 INET6_ATON 만 작동하더라도 (ipTo) 행 중 하나가 실패합니다.LOAD DATA LOCAL INFILE에서 INET6_ATON을 사용할 때 null 반환

내 테이블 : 4 fileds

`geoIPID` INT NOT NULL AUTO_INCREMENT , 
`IPFrom` VARBINARY(16) NOT NULL , 
`IPTo` VARBINARY(16) NOT NULL , 
`countries_countryID` INT NOT NULL 

테이블에 텍스트 파일을로드하는 스크립트 :

LOAD DATA LOCAL INFILE '/Users/Invictus/Documents/htdocs/overkill/etcs/IPV6.csv' 
INTO TABLE `overkill`.`geoIP` 
    FIELDS TERMINATED BY ',' ENCLOSED BY '"' 
    LINES TERMINATED BY '\n' 
(@IPFrom, @IPTo, @dummy, @dummy, @countryAbbreviation, @dummy) 
SET IPFrom = IF(IS_IPV4(@IPFrom), 
       INET_ATON(@IPFrom), 
       INET6_ATON(@IPFrom)), 
    IPTo = IF(IS_IPV4(@IPTo), 
       INET_ATON(@IPTo), 
       INET6_ATON(@IPTo)), 
    countries_countryID = 
    (
     SELECT IF (COUNT(*) != 0, `countries`.`countryID`, 999) 
     FROM `countries` 
     WHERE `countries`.`countryAbbreviation` = @countryAbbreviation 
     LIMIT 1 
    ); 

IPV4.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" 
이 같은 17,451,515,

IPV6.csv 파일 :

"2001:200::", "2001:200:ffff:ffff:ffff:ffff:ffff:ffff", "42540528726795050063891204319802818560", "42540528806023212578155541913346768895", "JP", "Japan" 
"2001:208::", "2001:208:ffff:ffff:ffff:ffff:ffff:ffff", "42540529360620350178005905068154421248", "42540529439848512692270242661698371583", "SG", "Singapore" 
"2001:218::", "2001:218:ffff:ffff:ffff:ffff:ffff:ffff", "42540530628270950406235306564857626624", "42540530707499112920499644158401576959", "JP", "Japan" 

내 문제 : 경우

내가 IPv6로드는 두 번째 행 (ipTo)NULL입니다. 왜? 파일의 모든 값은 유효하지만, MySQL은 변환하지 않습니다.

답변

2

문제는 INET6_ATON이 아니라 IPV6.csv 파일에 있습니다. IPV4.csv 달리 쉼표 후 여분의 공백이 있고 그 LOAD DATA

"2001:200:ffff:ffff:ffff:ffff:ffff:ffff" 
^^         ^

처럼 두 번째 필드를 읽을하게하고 그 이유를 INET6_ATON 반환 NULL입니다. 당신이 당신의 쿼리를 단순화하고 단지 전환 조건부 INET6_ATON를 사용하는 대신 수 있습니다 게다가

  1. 을하거나 CSV 파일
  2. 에 여분의 공백을 제거하거나 FIELDS TERMINATED BY ', '

에 구분 기호를 변경합니다

이 문제를 해결하려면 INET_ATONINET6_ATON 사이 후자는 IPV4와 IPV6 모두에서 잘 작동합니다.

말했다되고 그건 다음과 같을 수 쿼리 (당신이 CSV 파일에 여분의 공백이없는 가정 )

LOAD DATA LOCAL INFILE '/Users/Invictus/Documents/htdocs/overkill/etcs/IPV6.csv' 
INTO TABLE `overkill`.`geoIP` 
    FIELDS TERMINATED BY ',' ENCLOSED BY '"' 
    LINES TERMINATED BY '\n' 
(@ipfrom, @ipto, @dummy, @dummy, @abbr, @dummy) 
SET IPFrom = INET6_ATON(@ipfrom), 
    IPTo = INET6_ATON(@ipto), 
    countries_countryID = 
    (
     SELECT IF(COUNT(*) != 0, `countries`.`countryID`, 999) 
     FROM `countries` 
     WHERE `countries`.`countryAbbreviation` = @abbr 
     LIMIT 1 
    ); 

내가 여분의 공백을 제거했습니다 밖으로 물건을 모두 결합을 테스트하려면 파일을 읽고 ipv6 테이블에로드했습니다. 결과는 다음과 같습니다.

 
mysql> select geoIPID, HEX(ipfrom), HEX(ipto) from ipv6; 
+---------+----------------------------------+----------------------------------+ 
| geoIPID | HEX(ipfrom)      | HEX(ipto)      | 
+---------+----------------------------------+----------------------------------+ 
|  1 | 20010200000000000000000000000000 | 20010200FFFFFFFFFFFFFFFFFFFFFFFF | 
|  2 | 20010208000000000000000000000000 | 20010208FFFFFFFFFFFFFFFFFFFFFFFF | 
|  3 | 20010218000000000000000000000000 | 20010218FFFFFFFFFFFFFFFFFFFFFFFF | 
|  4 | 01000000       | 010000FF       | 
|  5 | 01000100       | 010003FF       | 
|  6 | 01000400       | 010007FF       | 
+---------+----------------------------------+----------------------------------+ 
6 rows in set (0.00 sec) 

mysql> select geoIPID, INET6_NTOA(ipfrom), INET6_NTOA(ipto) from ipv6; 
+---------+--------------------+----------------------------------------+ 
| geoIPID | INET6_NTOA(ipfrom) | INET6_NTOA(ipto)      | 
+---------+--------------------+----------------------------------------+ 
|  1 | 2001:200::   | 2001:200:ffff:ffff:ffff:ffff:ffff:ffff | 
|  2 | 2001:208::   | 2001:208:ffff:ffff:ffff:ffff:ffff:ffff | 
|  3 | 2001:218::   | 2001:218:ffff:ffff:ffff:ffff:ffff:ffff | 
|  4 | 1.0.0.0   | 1.0.0.255        | 
|  5 | 1.0.1.0   | 1.0.3.255        | 
|  6 | 1.0.4.0   | 1.0.7.255        | 
+---------+--------------------+----------------------------------------+ 
6 rows in set (0.00 sec)