我的 Sql Bulk 插入加载数据并截断

Posted

技术标签:

【中文标题】我的 Sql Bulk 插入加载数据并截断【英文标题】:My Sql Bulk inserts loading the data with truncating 【发布时间】:2019-03-04 02:49:15 【问题描述】:

我正在尝试通过批量插入选项将数据从 CSV 文件加载到 mysql 数据库。下面是创建表的语法和 CSV 文件

CREATE TABLE discounts (
    id INT NOT NULL ,
    title VARCHAR(10) NOT NULL,
    expired_date DATE NOT NULL,
    amount VARCHAR(255 ) NOT NULL

);

CSV 文件格式:

"475","Back","20140401","FFFF"
"476","bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","20140901","DDD"

SQL 查询:

LOAD DATA  INFILE 'C:\Users\karthick\Desktop\data.csv' 
INTO TABLE discounts 
FIELDS TERMINATED BY ',' 
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n';

在上面的创建表语法中,我已将“标题”列的数据长度指定为“10”。但是数据文件中第二行的值超过了10。

当我执行 SQL 查询时,数据已成功加载到 MySQL 数据库,这是以下输出,第二行中的“标题”字段的值被截断。您能否建议如何在不截断行的情况下停止加载行。如果数据合适,它还应该加载下一个连续行而不终止。请推荐

数据库输出:

'475', 'Back', '2014-04-01', 'FFFF'
'476', 'bbbbbbbbbb', '2014-09-01', 'DDD'

【问题讨论】:

使用title VARCHAR(100)?我的意思是,如果字段的固定宽度为 10,那么它只能存储 10 个字符,对吧? 我希望数据库在数据长度超过限制的情况下会抛出错误。有没有可能?请建议 你知道这个数据的最大宽度吗?如果是这样,那么只需创建适当的表并加载数据。 我知道数据的宽度,但在某些情况下可能会违反。那么有没有可能拒绝数据库端的完整行?我的目标是该行应该被拒绝。 我在下面给了你一个答案,只有一个选项。可能还有其他方法。 【参考方案1】:

这是您可以使用的技巧。假设您要持久化的最大宽度title 是 100 个字符,您可以按如下方式创建表格:

CREATE TABLE discounts (
    id INT NOT NULL,
    title VARCHAR(101) NOT NULL,    -- slightly larger than desired max width
    expired_date DATE NOT NULL,
    amount VARCHAR(255 ) NOT NULL
);

然后照常加载您的数据。标题超过宽度为 100 的记录实际上在数据库表中的宽度为 101。然后,您可以针对此类记录进行删除:

DELETE
FROM discounts
WHERE LENGTH(title) > 100;

如果需要,您现在还可以将 title 列的宽度调整为 100:

ALTER TABLE discounts MODIFY COLUMN title VARCHAR(100);

可能可以从LOAD DATA 那里获得此功能,但总的来说,此工具相当简单,旨在将数据盲目地加载到 MySQL 表中。 LOAD DATA 确实能够在读取数据时对其进行转换,但我不确定它是否可以阻止它。

【讨论】:

这是一个耗时的过程,假设我有 200 列的 100 万条记录。例如,如果我在 10 列中有漏洞,则上述建议的答案将花费很多时间。我正在寻找类似 oracle 的选项,在同样的情况下,oracle 将拒绝完整的记录,并且相同的记录将被记录到“*.bad.CSV”文件中。我也在 MySql 中寻找类似的选项。 那我没有给你答案,抱歉。但是,除非其他人有更好的主意,否则我会留下这个。 是的蒂姆,我们也会等待其他活跃的专家。非常感谢您的信息【参考方案2】:

根据我的理解,以下是您想要实现的几点: 1) 如果标题长度超过表结构中指定的字段长度,则不应截断数据。 2) 如果标题长度更长,则在导入记录时应跳过该记录,其余过程应继续进行。

根据mysql数据库考虑回答:

您可以将 sql_mode 用作 TRADITIONAL(使 MySQL 的行为类似于“传统”SQL 数据库系统。此模式的简单描述是在向列中插入不正确的值时“给出错误而不是警告”。参考:https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html)

现在设置此模式后,在进行记录导入时,如果将任何不正确的数据或超出范围的值插入到表中,则会出现错误。

下一部分,对于超出范围的值,它们无法跳过错误行。您可以查看现有的讨论链接:Skip error lines while loading data to mysql table from delimited file

对于跳过破坏唯一约束或可能创建重复记录的行,可以使用 IGNORE 关键字和 LOAD DATA INFILE 跳过。

参考:https://dev.mysql.com/doc/refman/5.5/en/load-data.html

【讨论】:

以上是关于我的 Sql Bulk 插入加载数据并截断的主要内容,如果未能解决你的问题,请参考以下文章

SQL在插入时如何截断数据?

员工维度在数据仓库中每天被截断

插入 SQL Server 时 Pentaho 错误数据被截断

如何在 SQL Standard 上导出 SSIS 数据并在 SQL Express 上使用 Bulk Insert 导入?

Sql server bulk insert文本文件插入到数据库

SQL SERVER 使用BULK Insert将txt文件中的数据批量插入表中