MySQL通过String加载CSV文件

时间:2012-02-27 09:45:34

标签: mysql string csv insert

我可以通过phpmyadmin导入我的csv文件(但需要很长时间)。我无法通过SSH和MySQL作为命令加载它,因为我没有这个权限。

因此有可能像这样加载csv数据:

    INSERT INTO table LOAD_CSV(MY_CSV_STRING)

如果不是,我必须将其解析为单独的行。

5 个答案:

答案 0 :(得分:2)

实际上没有办法做我想做的事。只能通过文件加载它。

答案 1 :(得分:1)

您可以这样使用LOAD DATA INFILE

LOAD DATA LOCAL INFILE '/importfile.csv' 
INTO TABLE test_table 
FIELDS TERMINATED BY ',' 
LINES TERMINATED BY '\n' 
(field1, filed2, field3);

答案 2 :(得分:0)

可以将此存储过程与SUBSTRING_INDEX结合使用。请注意,如果您的CSV太大,则可能需要使用LOCATE和SUBSTRING。这是一个简单的参考:

CREATE PROCEDURE load_csv (IN `icsv` MEDIUMTEXT)
    MOD_SP
    BEGIN
        DECLARE csv MEDIUMBLOB;
        DECLARE csv_begin INTEGER DEFAULT 1;
        DECLARE csv_end INTEGER;
        DECLARE csv_size INTEGER;
        SET csv = COALESCE(`icsv`,'');
        SET csv_size = LENGTH(csv);
        WHILE csv_begin < csv_size DO
            SET csv_end = LOCATE('\n',csv,csv_begin);
            SET csv_end = IF(csv_end != 0,csv_end,csv_size+1);
            SET pbegin = pend+1;
            INSERT INTO mytable (field1, field2, field3, field4, field5) VALUES (
                SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(policy FROM pbegin FOR pend-pbegin),',',1),-1),
                SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(policy FROM pbegin FOR pend-pbegin),',',2),-1),
                SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(policy FROM pbegin FOR pend-pbegin),',',3),-1),
                SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(policy FROM pbegin FOR pend-pbegin),',',4),-1),
                SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(policy FROM pbegin FOR pend-pbegin),',',5),-1)
            )
        END WHILE;
    END //

你可以通过一些优化来加快速度,特别是缓存csv行并使用SUBSTRING_INDEX的一些属性来获得最小的字符串。

CREATE PROCEDURE load_csv (IN `icsv` MEDIUMTEXT)
    MOD_SP
    BEGIN
        DECLARE csv MEDIUMBLOB;
        DECLARE csv_line MEDIUMBLOB;
        DECLARE csv_begin INTEGER DEFAULT 1;
        DECLARE csv_end INTEGER;
        DECLARE csv_size INTEGER;
        SET csv = COALESCE(`icsv`,'');
        SET csv_size = LENGTH(csv);
        WHILE csv_begin < csv_size DO
            SET csv_end = LOCATE('\n',csv,csv_begin);
            SET csv_end = IF(csv_end != 0,csv_end,csv_size+1);
            SET csv_line = SUBSTRING(policy FROM pbegin FOR pend-pbegin);
            SET pbegin = pend+1;
            INSERT INTO mytable (field1, field2, field3, field4, field5) VALUES (
                SUBSTRING_INDEX(csv_line,',',1),
                SUBSTRING_INDEX(SUBSTRING_INDEX(csv_line,',',2),-1),
                SUBSTRING_INDEX(SUBSTRING_INDEX(csv_line,',',3),-1),
                SUBSTRING_INDEX(SUBSTRING_INDEX(csv_line,',',-2),1),
                SUBSTRING_INDEX(csv_line,',',-1)
            )
        END WHILE;
    END //

最后,如果您的线条特别长但我没有时间编写此示例,您甚至可以使用逗号和子串的混合编写。

答案 3 :(得分:0)

使用LOAD DATA LOCAL INFILE命令导入aleroot建议。

如果存在权限错误,则需要通过使用以下命令连接到mysql实例来允许它: mysql - local-infile -uroot -p

答案 4 :(得分:0)

使用动态SQL的解决方案

CREATE PROCEDURE load_csv(IN CSV_INPUT LONGTEXT)
/*

 CALL load_csv(@csv:='a1,b1,c1\na2,b2,c2\na3,b3,c3')
 */
BEGIN
    SET CSV_INPUT := @csv;

    SET @sql = concat('INSERT INTO mytable (field1, field2, field3)
            VALUES ("', replace(replace(CSV_INPUT, ',', '","'), '\n', '"),("'), '");');
    PREPARE stmt1 FROM @sql;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;
END;