1

这是我的第一篇 Stack Overflow 帖子!社区提供了很大的帮助!

我有一个 90K 行的 CSV 我试图通过一个带有 CSV 的临时表插入到一个表中,例如:

CREATE TEMPORARY TABLE temp_product like product;
LOAD DATA LOCAL INFILE "myfile.csv"
...

但我试图通过一个包含事务的过程和一个退出处理程序来结束插入和一些额外的操作,以防万一任何失败或引发警告:

CREATE PROCEDURE update_products ()
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND, SQLWARNING ROLLBACK;
    START TRANSACTION;
    ....

我喜欢这种方法,因为它允许我在遇到任何错误时自动回滚,并且还可以很好地包装整个逻辑事务块。唉:

Error : LOAD DATA is not allowed in stored procedures

(我不确定这是为什么?我想它只是还不支持?)我不确定我的语法是否正确(或者如果这甚至可能)但我什至可以接受类似的东西:

DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND, SQLWARNING ROLLBACK;
START TRANSACTION;

但这会引发明显的语法错误:

Error : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND, SQLWARNING ROLLBACK' at line 1

如果我可以以不同的方式加载 CSV,我似乎可以完成这项工作,但我可能会失去批量插入的速度,和/或必须使用基于磁盘的表,因为我可能需要与它建立多个连接。据我了解,临时表只存在于单个连接/事务,我不能 100% 确定我的 MySQL 客户端 Navicat 是如何管理这个的。

如果这是管理脚本的最明智的方法,该脚本在使用LOAD DATA.

随意告诉我,我也完全错误地处理了这个问题。我觉得可能有一种更聪明的方法来做我正在做的事情。

4

1 回答 1

2

不幸的是,不支持LOAD DATA INFILE存储过程。我确实记得曾经看到有人使用 MySQL 存储过程调用 shell 脚本来实际执行上传的解决方法,但这似乎是一个潜在的问题解决方案,安全方面。你也许可以用谷歌搜索这个解决方案。

最好的选择可能是使用某种脚本(PHP、shell 等)来执行加载到临时表中,然后调用存储过程来实际填充到永久表中。我认为只要您对这部分有事务支持,您就可以回滚真正重要的部分(填充永久表)。

于 2012-12-25T00:04:05.713 回答