我有一些非常大的文件(数百万条记录)需要加载到数据库中。它们的形式如下:
word1\tblahblahblah
word2\tblahblah
word3\tblahblah
word4
word5\tblahblah
...
我的问题是,我想忽略没有第二条记录的行( 'blahblah's'),比如word4。
我目前使用以下查询来加载该文件:
LOAD DATA LOCAL INFILE 'file'
IGNORE INTO TABLE tablename
COLUMNS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
(col1, col2);
它具有我想要的功能,只是它仍然接受空值。有没有办法跳过word4类型行而不将它们添加到DB中?
直觉上,我认为使用WHEN或WHERE子句将是完美的,但在线查看文档和其他信息时,我找不到任何适用的示例。我是不是必须事先过滤掉这些记录,或者我可以在这个查询中这样做?
如有任何帮助,grealy将非常感谢!
发布于 2011-09-29 02:52:14
为此,我会使用grep
或awk
过滤文件,然后将其通过管道传输到MySQL (通过/dev/stdin
)。如下所示:
cat your_file.txt |
awk '/\t.+/' |
mysql -u your_username -pyour_password \
-e "LOAD DATA LOCAL INFILE '/dev/stdin' \
IGNORE INTO TABLE tablename \
COLUMNS TERMINATED BY '\t' \
LINES TERMINATED BY '\n' \
(col1, col2);" \
your_database_name
第二行中给出的awk
正则表达式只匹配任何后跟一个或多个字符的制表符的行。您可能希望对其进行调整以满足您的需要。
编辑:我想到了另一种可能性。您可以使用SET
在空白的列上设置一些魔术值,并在表上放置一个BEFORE INSERT
触发器,当它看到该值时,该触发器将对一行进行回滚。我对触发器没有太多的经验,但我认为这样的东西应该可以工作:
CREATE TRIGGER skip_magic_rows
BEFORE INSERT ON tablename
FOR EACH ROW
BEGIN
IF NEW.col2 = 'IDSPISPOPD4815162342' THEN # Some unlikely magic string
# Trigger an error, which will cause the INSERT to fail†
# If you have MySQL < 5.5 this is kludgy -- see Note 1
DROP TABLE `Skipped row`
# OR
# In MySQL >= 5.5 you can send a signal--'45000' is a generic error
SIGNAL SQLSTATE '45000' SET message_text = 'Skipped row'; # See Note 2
END IF
END
;
在BEFORE或AFTER触发器期间的错误会导致导致触发器调用的整个语句失败。
然后..。
LOAD DATA LOCAL INFILE 'file'
IGNORE INTO TABLE tablename
COLUMNS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
(col1, @var2)
SET col2 = IF(@var2 IN (NULL, ''), 'IDSPISPOPD4815162342', @var2)
;
希望对您有帮助!
备注1: Relevant blog post and comments
注释2: Relevant SO thread
https://stackoverflow.com/questions/7587660
复制相似问题