尝试做LOAD DATA INFILE与REPLACE和AUTO_INCREMENT(Trying

2019-06-24 22:35发布

我想一个文件加载到MySQL数据库,具有主键auto_incremented,我想对数据进行更新,如果我找到任何重复的行。 然而,替换关键字仅适用于主键,这是生成的,所以我卡住了汽车。

如何能够有一个ID是auto_increments,并在同一时间能够插入使用LOAD DATA INFILE文件/更新数据的表?

下面是表

CREATE TABLE  `oxygen_domain`.`TEST` (
`TEST_ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(255) NOT NULL,
`VALUE` varchar(255) DEFAULT NULL,
PRIMARY KEY (`TEST_ID`,`NAME`,`VALUE`)
) 

这里是命令

LOAD DATA LOCAL INFILE 'C:/testData.txt'
REPLACE
INTO TABLE TEST
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES
(NAME, VALUE);

这里是样本数据

ignored name, ignored value
name1,value1
name2,value2
name3,value3

任意不等阶以上数据上面运行多次的命令后,想结束结果

|TEST_ID |NAME |VALUE|
1, 'name1', 'value1'
2, 'name2', 'value2'
3, 'name3', 'value3'

Answer 1:

观察#1

你不应该做REPLACE ,因为它是一个机械DELETEINSERT

正如MySQL文档说,有关更换

第2

取而代之的是一个MySQL扩展到SQL标准。 它无论是插入或删除和插入。 对于另一个MySQL扩展到标准SQL-,要么插入或更新,请参见13.2.5.3,“插入...对重复密钥更新语法”。

第5

要使用REPLACE,您必须同时拥有,插入和删除表的权限。

使用REPLACE将引发无法自动重新用于为test_id远成立的值。

观察#2

这个表格布局不支持重复键的陷阱

如果名称是唯一的,表应当设置这样的

布局#1

CREATE TABLE  `oxygen_domain`.`TEST` (
`TEST_ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(255) NOT NULL,
`VALUE` varchar(255) DEFAULT NULL,
PRIMARY KEY (`TEST_ID`),
KEY (`NAME`)
) 

如果名称允许多个值,表应当设置这样的

布局#2

CREATE TABLE  `oxygen_domain`.`TEST` (
`TEST_ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(255) NOT NULL,
`VALUE` varchar(255) DEFAULT NULL,
PRIMARY KEY (`TEST_ID`),
KEY (`NAME`,`VALUE`)
) 

提出的解决方案

使用临时表来捕获一切。 然后,根据布局执行从临时表中一个很大的INSERT

布局#1

更换VALUE是否有重复的NAME

USE oxygen_domain
DROP TABLE IF EXISTS `TESTLOAD`;

CREATE TABLE `TESTLOAD` SELECT NAME,VALUE FROM TEST WHERE 1=2;

LOAD DATA LOCAL INFILE 'C:/testData.txt'
INTO TABLE `TESTLOAD`
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES
(NAME, VALUE);

INSERT INTO `TEST` (NAME, VALUE)
SELECT NAME, VALUE FROM `TESTLOAD`
ON DUPLICATE KEY UPDATE VALUE = VALUES(VALUE);

DROP TABLE `TESTLOAD`;

布局#2

忽略重复(NAME,VALUE)的行

USE oxygen_domain
DROP TABLE IF EXISTS `TESTLOAD`;

CREATE TABLE `TESTLOAD` SELECT NAME,VALUE FROM TEST WHERE 1=2;

LOAD DATA LOCAL INFILE 'C:/testData.txt'
INTO TABLE `TESTLOAD`
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES
(NAME, VALUE);

INSERT IGNORE INTO `TEST` (NAME, VALUE)
SELECT NAME, VALUE FROM `TESTLOAD`;

DROP TABLE `TESTLOAD`;

更新

如果我们需要避免表的每一次创建和删除。 我们可以截断TRUNCATE之前或使用INSERT ... INTO语句后表。 因此,我们不必创建表下一次。



Answer 2:

在名称和值来创建唯一索引并使用忽略,而不是更换:

LOAD DATA LOCAL INFILE 'C:/testData.txt'
IGNORE
INTO TABLE `TEST`
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES
(NAME, VALUE);


Answer 3:

只是删除从LOAD DATA替换,执行它两次,你会得到期望的结果:

LOAD DATA LOCAL INFILE 'C:/testData.txt'
INTO TABLE TEST
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES
(NAME, VALUE);

我想你真的不希望你张贴的所有期望的结果,你呢?



文章来源: Trying to do LOAD DATA INFILE with REPLACE and AUTO_INCREMENT