在LOAD DATA LOCAL INFILE中使用INET6_ATON时返回null

时间:2013-08-03 23:54:44

标签: mysql ipv6 inet-aton

我正在使用MySQL 5.6,尝试使用新功能,例如INET6_ATONIS_IPV6。 当脚本读取IPV4时,它会将数据完美地插入表中。但是当谈到IPv6时,其中一行[{1}}会失败,即使(ipTo)单独工作。

我的表:4个文件

INET6_ATON

一个脚本,用于将文本文件加载到表中:

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

IPV4.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, @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
    );

IPV6.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"

我的问题:

如果我加载"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)。为什么?文件中的所有值都是有效的,MySQL仍然没有转换它们。

1 个答案:

答案 0 :(得分:2)

问题不在INET6_ATON中,而在IPV6.csv文件中。与IPV4.csv不同,您在逗号后面有额外的空格,这使LOAD DATA像这样读取您的第二个字段

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

这就是INET6_ATON返回NULL的原因。

解决此问题:

  1. 删除csv文件中的额外空格
  2. 或将分隔符更改为FIELDS TERMINATED BY ', '
  3. 此外,您可以简化查询,只需使用INET6_ATON,而不是在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)