我正在使用 MySQL 5.7 与 Node JS 6.11.0 ,并且每当我插入冲突的行时,我都会尝试更新UNIQUE
MySQL列。但是,当我尝试插入冲突记录时,只有现有记录更新为NULL
且不会发生insert
。这是我的代码
pool.getConnection(function(err, connection) {
var newClass = req.body;
var query = `INSERT INTO classes SET ? ON DUPLICATE KEY UPDATE teacher_id = NULL`;
connection.query(query, newClass, function(err, result) {
console.log(result);
if(result.affectedRows >= 1) {
res.status(201).end();
res.json(result);
}
});
connection.release();
});`
我必须为要插入的行运行两次查询;第一次将冲突列设置为null,然后当我再次运行相同的查询时,插入该行,因为没有冲突。
我已经生成了SQL并直接从MySql控制台运行它,我仍然需要为要插入的新行运行两次查询。我不明白为什么这样做。
Sql语句是
INSERT INTO classes SET `stream` = 'Red', `form` = '1', `teacher_id` = '7' ON DUPLICATE KEY UPDATE teacher_id = NULL
我的创建表SQL是
| classes | CREATE TABLE `classes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`form` varchar(10) NOT NULL,
`stream` varchar(15) NOT NULL,
`teacher_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `teacher_id` (`teacher_id`),
CONSTRAINT `classes_ibfk_1` FOREIGN KEY (`teacher_id`) REFERENCES `teachers`
( `id` )
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=latin1 |`
为什么MySQL会这样表现?
答案 0 :(得分:7)
INSERT INTO classes
SET stream = 'Red', form = '1',teacher_id = '7'
ON DUPLICATE KEY UPDATE teacher_id = NULL;
在存在冲突记录(重复的唯一键或主键)时告诉MySQL,将有问题的行的teacher_id
列设置为null
并停止。
您有几种方法可以达到理想的效果。
首先,您可以使用REPLACE
语法。
REPLACE INTO classes SET stream = 'Red', form = '1', teacher_id = '7';
首先使用UNIQUE或Primary Key约束删除违规行,然后插入具有指定值的新行。缺点是任何省略的列值都将丢失并设置为其默认值。如果未在查询中指定,还将创建新的自动生成(如果有)id。
如果没有违规记录,则会发生正常的INSERT
。
否则,您可以在VALUES
子句中使用UPDATE
。
INSERT INTO classes
SET stream = 'Red', form = '1', teacher_id = '7'
ON DUPLICATE KEY UPDATE stream = VALUES(stream),
form = VALUES(form);
相反,这会将违规行的记录更新为查询的INSERT
部分中指定的值。
参考文献:
根据新意图更新
要在离开上一行时创建新记录,您需要先使现有行上的UNIQUE
约束无效,然后才能使用INSERT
。
目前没有方法可以在单个查询中使用MySQL。
由于INSERT
的限制,完成所需操作的最简单方法是在UPDATE
查询之前运行INSERT
查询。
UPDATE classes
SET teacher_id = NULL
WHERE teacher_id = '7';
INSERT INTO classes
SET stream = 'Red',
form = '1',
teacher_id = '7';
这将首先检查有冲突的teacher_id
记录并将其设置为null
。如果不存在冲突记录,则不会进行更新。然后,以下INSERT
将创建所需的记录,而不会发生冲突。
答案 1 :(得分:2)
如果要根据条件插入数据,请尝试使用
INSERT INTO table1 SELECT 'Red',1,7 FROM table2 where teacher_id IS NULL;
否则,如果您想根据尝试进行更新。
update table1 SET stream = 'Red', form = '1', teacher_id = '7' where teacher_id IS NULL;
注意:NULL = NULL实际上不是FALSE - 它再次为NULL。但它也不是TRUE,因此IF(NULL = NULL)不会执行 例如,即使对NULL本身,NULL也将测试FALSE。因此,只使用前面提到的函数(和IS NULL())来处理NULL。您的查询可以按上述方式重写。