我正在尝试将一个文件加载到 MySQL 数据库中,主键为 auto_incremented,如果我发现任何重复的行,我希望更新数据。但是,REPLACE 关键字仅适用于自动生成的主键,所以我被卡住了。
如何能够拥有一个 ID 自动递增的表,同时能够使用 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'
最佳答案
观察#1
您不应该执行 REPLACE
,因为它是机械的 DELETE
和 INSERT
。
作为MySQL Documentation说关于替换
第 2 段
REPLACE is a MySQL extension to the SQL standard. It either inserts, or deletes and inserts. For another MySQL extension to standard SQL—that either inserts or updates—see Section 13.2.5.3, “INSERT ... ON DUPLICATE KEY UPDATE Syntax”.
第 5 段
To use REPLACE, you must have both the INSERT and DELETE privileges for the table.
使用 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 语句之前或之后的表。因此,我们下次不必创建表。
关于mysql - 尝试使用 REPLACE 和 AUTO_INCREMENT 执行 LOAD DATA INFILE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10801302/