2 votes

Renvoi de null lors de l'utilisation de INET6_ATON dans LOAD DATA LOCAL INFILE

J'utilise MySQL 5.6 et j'expérimente les nouvelles fonctionnalités, telles que INET6_ATON y IS_IPV6 . Lorsque le script lit IPV4 il insère parfaitement les données dans le tableau. Mais lorsqu'il s'agit de IPv6 , une des lignes (ipTo) échoue, même si le INET6_ATON travaille seul.

Ma table : 4 dossiers

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

Un script, qui charge les fichiers texte dans le tableau :

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
    );

Le fichier IPV4.csv, comme ceci :

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

Le fichier IPV6.csv, comme ceci :

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

Mon problème :

Dans le cas où je charge le IPv6 , la deuxième ligne (ipTo) es NULL . Pourquoi ? Toutes les valeurs des fichiers sont valides, mais MySQL ne les convertit pas.

2voto

peterm Points 72466

Le problème n'est pas dans INET6_ATON mais dans votre IPV6.csv dossier. Contrairement à IPV4.csv vous avez des espaces supplémentaires après les virgules et cela rend les LOAD DATA lisez votre deuxième champ comme suit

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

et c'est pourquoi INET6_ATON retours NULL .

Pour y remédier :

  1. soit vous supprimez les espaces supplémentaires dans votre fichier csv
  2. ou changer le délimiteur en FIELDS TERMINATED BY ', '

En outre, vous pouvez simplifier votre requête et utiliser simplement INET6_ATON au lieu de passer conditionnellement de l'un à l'autre INET_ATON y INET6_ATON . Ce dernier fonctionne parfaitement avec IPV4 et IPV6.

Ceci étant dit, votre requête pourrait ressembler à ceci ( en supposant que vous n'avez pas d'espaces supplémentaires dans le fichier 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
    );

Pour tester les choses, j'ai supprimé les espaces supplémentaires, combiné vos deux fichiers et les ai chargés dans le fichier ipv6 table. Voici le résultat

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)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X