web-dev-qa-db-fra.com

Comment ignorer une ligne lors de l'importation d'un mauvais vidage MySQL

Étant donné un mauvais mysqldump qui provoque une erreur lors de l'importation:

namtar backups # mysql -p < 2010-12-01.sql
Enter password: 
ERROR 1062 (23000) at line 8020: Duplicate entry 'l�he?' for key 'wrd_txt'

Existe-t-il un moyen facile de dire à l'importation de simplement sauter une ligne donnée et de continuer?

(Oui, je sais que je peux modifier manuellement le fichier ou analyser la sortie, mais ce n'est pas très pratique)

35
Almad

Si vous pouvez refaire le vidage, vous pouvez ajouter --insert-ignore à la ligne de commande lors du vidage.

Ou vous pouvez essayer d'utiliser la commande mysqlimport avec --force, qui continuera même s'il rencontre des erreurs MySQL.

46
jmlsteele

mysql -f -p < 2010-12-01.sql

le -f (force) étant l'option opérationnelle ici, a fonctionné pour moi.

36

En suivant les conseils de la réponse et du commentaire de jmlsteele, voici comment transformer les insertions en INSERT IGNORE à la volée.

Si vous importez à partir d'un fichier sql:

sed -e "s/^INSERT INTO/INSERT IGNORE INTO/" < 2010-12-01.sql | mysql -p

Si vous importez à partir d'un fichier gz, dirigez simplement la sortie de gunzip dans sed au lieu d'utiliser l'entrée de fichier:

gunzip < 2010-12-01.sql.gz | sed -e "s/^INSERT INTO/INSERT IGNORE INTO/" | mysql -p
22
Ben

Les autres options sont certainement des options viables, mais une autre solution serait de simplement modifier le .sql fichier obtenu à partir du mysqldump.

Changement:

INSERT INTO table_name ...

À

INSERT IGNORE INTO table_name ...
1
PromInc

Juste une pensée avez-vous supprimé les directives MySQL en haut du vidage? (Je l'ai fait involontairement lorsque j'ai redémarré une restauration après avoir supprimé tous les enregistrements/tables que j'avais déjà insérés avec une commande sed). Ces directives indiquent à MySQL, entre autres, de ne pas faire de tests uniques, de tests de clés étrangères, etc.)

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
1
zzapper

Bon conseil. Je l'ai fait un peu différent mais le même résultat.

Perl -pi -e 's/INSERT INTO/INSERT IGNORE INTO/g' filename.sql
0
Robert Saylor