【问题标题】:LOAD DATA INFILE consistently skips first line, while not set to IGNORELOAD DATA INFILE 始终跳过第一行,但未设置为 IGNORE
【发布时间】:2020-06-26 21:39:57
【问题描述】:

我正在尝试将包含股票价格的 csv 文件加载到价格表中。 csv 文件有 3 行我想忽略,包括一个空白行。 当我设置IGNORE 1 LINES 时,它会在处理列标题时遇到错误。 当我设置IGNORE 2 LINES 时,它始终跳过第一行数据。 从第二个数据行(在本例中为“11-03-2020”)开始,所有其他数据都加载得很好。

如何在不更改 csv 中的数据的情况下解决此问题?

csv 如下所示:

"Some instructions"

"date";"price"
"12-03-2020";133.08
"11-03-2020";143.68
"10-03-2020";149.14
...

创建表代码:

CREATE TABLE `prices` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `isin` CHAR(12) NOT NULL,
    `price_date` DATE NOT NULL,
    `price` DECIMAL(10,2) NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE INDEX `isin_date` (`isin`, `price_date`),
    CONSTRAINT `prices_stocks` FOREIGN KEY (`isin`) REFERENCES `stocks` (`isin`) ON UPDATE CASCADE ON DELETE NO ACTION
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
ROW_FORMAT=DYNAMIC
AUTO_INCREMENT=157532
;

LOAD DATA SQL 语句:

LOAD DATA LOCAL INFILE 'price_history_LU0792910050.csv'
        REPLACE INTO TABLE stock_db.prices
            CHARACTER SET utf8
            FIELDS TERMINATED BY ';'
            OPTIONALLY ENCLOSED BY '"'
            ESCAPED BY '"'
            LINES TERMINATED BY '\r\n'
            IGNORE 2 LINES
            (@vdate, @vprice)
        SET
            isin = 'LU0792910050',
            price_date = STR_TO_DATE(@vdate, '%d-%m-%Y'),
            price = @vprice;

示例 csv 的 hexdump:

00000000: EF BB BF 22 44 65 20 69  6E 73 74 65 6C 6C 69 6E  ..."De instellin
00000010: 67 65 6E 20 76 61 6E 20  75 77 20 45 78 63 65 6C  gen van uw Excel
00000020: 2D 73 6F 66 74 77 61 72  65 20 6B 75 6E 6E 65 6E  -software kunnen
00000030: 20 64 65 20 77 65 65 72  67 61 76 65 20 76 61 6E   de weergave van
00000040: 20 6F 6E 64 65 72 73 74  61 61 6E 64 65 20 67 65   onderstaande ge
00000050: 67 65 76 65 6E 73 20 62  65 C3 AF 6E 76 6C 6F 65  gevens be..nvloe
00000060: 64 65 6E 20 64 6F 6F 72  20 64 65 20 63 65 6C 6F  den door de celo
00000070: 70 6D 61 61 6B 20 76 61  6E 20 64 65 20 67 65 67  pmaak van de geg
00000080: 65 76 65 6E 73 63 61 74  65 67 6F 72 69 65 20 28  evenscategorie (
00000090: 62 69 6A 76 2E 20 61 61  6E 74 61 6C 20 69 6E 20  bijv. aantal in 
000000A0: 70 6C 61 61 74 73 20 76  61 6E 20 64 61 74 75 6D  plaats van datum
000000B0: 29 2E 22 0D 0A 0D 0A 22  64 61 74 65 22 3B 22 70  )."...."date";"p
000000C0: 72 69 63 65 22 0D 0A 22  31 35 2D 30 37 2D 32 30  rice".."15-07-20
000000D0: 32 30 22 3B 35 31 2E 37  36 0D 0A 22 31 34 2D 30  20";51.76.."14-0
000000E0: 37 2D 32 30 32 30 22 3B  35 31 2E 31 37 0D 0A 22  7-2020";51.17.."
000000F0: 31 33 2D 30 37 2D 32 30  32 30 22 3B 35 31 2E 30  13-07-2020";51.0
00000100: 33 0D 0A 22 31 30 2D 30  37 2D 32 30 32 30 22 3B  3.."10-07-2020";

(Synology 上没有安装 Hexdump,所以使用 Python hexdump。希望这能工作)

【问题讨论】:

  • 确保文件确实有 CRLF,而不仅仅是 LF。
  • 谢谢@RickJames 该文件有 CRLF 而不仅仅是 LF。还有其他想法或想法吗?这真的很奇特。
  • 获取前几行的十六进制转储;我们可能缺少一些东西。
  • @RickJames,我如何获得十六进制转储?如果您能添加一些说明,将不胜感激。
  • Unix 还是 Windows?

标签: csv mariadb load-data-infile


【解决方案1】:

"12-03-2020" 不能直接放入DATE 列。相反,将其放入@变量中,然后使用str_to_date(...)。 (如果您需要帮助,请告诉我们;有很多例子。)

我看到C3 AF,它是ï 的utf8,就像... beïnvloegen ... 一样——听起来“正确”吗? CHARACTER SET utf8 应该读取正确。

最初的EF BB BF 是“BOM”。我不知道LOAD FILE 是否足够聪明,可以默默地跳过它。这可能会导致您的问题。一种方法是编辑文件以删除前 3 个字节。

后来出现0D 0A 0D 0A,它与您对有 3 个标题行的描述相匹配,第二个是空白的。 LINES TERMINATED BY '\r\n' 应该是正确的。

【讨论】:

  • "12-03-2020" -> 我相信在上面的 SQL 语句中转换为日期之前,我确实将它放入了一个变量中。 “ï”确实是那里使用的字符... beïnvloeden ...是正确的并且意味着影响我猜它是“BOM”使加载文件关闭。我已调整脚本以删除标题之前的所有行以解决此问题,但我真的很好奇为什么会发生这种情况(并希望在加载之前跳过编辑)。顺便提一下……我显然不是专业人士,但看起来你像矩阵中的角色一样阅读十六进制。
  • @Joost - 呵呵。我回答了很多字符集问题,以至于我开发了一个网页,可以让我将几乎所有内容粘贴到其中;它将自动转换为十六进制,并推断出一些可能发生的错误情况。我为此感到特别自豪:stackoverflow.com/questions/38363566/…我很久以前就发现了BOM:mysql.rjweb.org/doc.php/charcoll#bom_byte_order_mark
猜你喜欢
  • 1970-01-01
  • 2015-03-11
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 2012-09-13
  • 2012-06-11
  • 1970-01-01
  • 2014-11-08
相关资源
最近更新 更多