我的 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 Server 时 Pentaho 错误数据被截断
如何在 SQL Standard 上导出 SSIS 数据并在 SQL Express 上使用 Bulk Insert 导入?