2023年8月3日发(作者:)

当SQLUPDATE遇到EXISTS()时直接上例⼦。user表:SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for user-- ----------------------------DROP TABLE IF EXISTS `user`;CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `class_id` int(11) DEFAULT NULL, `class_name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;-- ------------------------------ Records of user-- ----------------------------INSERT INTO `user` VALUES ('1', 'a', '1', '');INSERT INTO `user` VALUES ('2', 'b', '2', '');INSERT INTO `user` VALUES ('3', 'c', '1', '');INSERT INTO `user` VALUES ('4', 'd', '1', '');INSERT INTO `user` VALUES ('5', 'e', '2', '');INSERT INTO `user` VALUES ('6', 'f', '2', '');INSERT INTO `user` VALUES ('7', 'g', '3', '');INSERT INTO `user` VALUES ('8', 'h', '2', '');INSERT INTO `user` VALUES ('9', 'k', '2', '');INSERT INTO `user` VALUES ('10', 'm', '3', '');class表:SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for class-- ----------------------------DROP TABLE IF EXISTS `class`;CREATE TABLE `class` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;-- ------------------------------ Records of class-- ----------------------------INSERT INTO `class` VALUES ('1', '初级班');INSERT INTO `class` VALUES ('2', '中级班');INSERT INTO `class` VALUES ('3', '⾼级班');

要求:根据`user`.class_id查询,并⽤其更新`user`.class_name。注意:这⾥测试的是UPDATE 语句与 WHERE EXISTS 语句的执⾏顺序,所以请忽略表设计⽅⾯的问题吧。语句如下:UPDATE `user` uSET _name = ( SELECT class.`name` FROM-- `user` u, class WHERE _id = LIMIT 1)WHERE EXISTS ( SELECT 1 FROM-- `user`, class WHERE _id = )结果表明:UPDATE语句的WHERE语句如果是EXISTS,那每执⾏⼀条就会判断⼀下,成⽴则执⾏SET语句 -- 类似于遍历执⾏。另外,UPDATE的表不能出现在FROM语句中。

这⾥的问题在于,EXISTS是bool判断,⽽SELECT则返回集合,容易让⼈⼀头雾⽔。

其实⽤PLSQL来写,逻辑更清晰⼀些。这⾥放上⼀个Oracle的PLSQL吧 -- MySQL的语法略有不同,暂没查到~~-- 打开控制台输出set serveroutput on-- PLSQLDECLARE -- 设置光标 CURSOR c is SELECT id,`name` FROM class; -- 定义光标变量 pid %type; pname %type;BEGIN -- 打开光标 OPEN c; LOOP -- 循环取出光标中的数据 FETCH c INTO pid,pname; -- 取出的数据放⼊变量中 EXIT WHEN c%notfound; -- 退出条件

-- 更新数据 UPDATE `user` SET `user`.class_name = pname WHERE `user`.class_id = pid; END LOOP; CLOSE c; -- 对于ORACLE,默认的事务隔离级别是 read committed。所以需要commit COMMIT;-- dbms__line('涨薪完毕'); -- 控制台输出完成提⽰END;/ -- 执⾏

2023年8月3日发(作者:)

当SQLUPDATE遇到EXISTS()时直接上例⼦。user表:SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for user-- ----------------------------DROP TABLE IF EXISTS `user`;CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `class_id` int(11) DEFAULT NULL, `class_name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;-- ------------------------------ Records of user-- ----------------------------INSERT INTO `user` VALUES ('1', 'a', '1', '');INSERT INTO `user` VALUES ('2', 'b', '2', '');INSERT INTO `user` VALUES ('3', 'c', '1', '');INSERT INTO `user` VALUES ('4', 'd', '1', '');INSERT INTO `user` VALUES ('5', 'e', '2', '');INSERT INTO `user` VALUES ('6', 'f', '2', '');INSERT INTO `user` VALUES ('7', 'g', '3', '');INSERT INTO `user` VALUES ('8', 'h', '2', '');INSERT INTO `user` VALUES ('9', 'k', '2', '');INSERT INTO `user` VALUES ('10', 'm', '3', '');class表:SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for class-- ----------------------------DROP TABLE IF EXISTS `class`;CREATE TABLE `class` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;-- ------------------------------ Records of class-- ----------------------------INSERT INTO `class` VALUES ('1', '初级班');INSERT INTO `class` VALUES ('2', '中级班');INSERT INTO `class` VALUES ('3', '⾼级班');

要求:根据`user`.class_id查询,并⽤其更新`user`.class_name。注意:这⾥测试的是UPDATE 语句与 WHERE EXISTS 语句的执⾏顺序,所以请忽略表设计⽅⾯的问题吧。语句如下:UPDATE `user` uSET _name = ( SELECT class.`name` FROM-- `user` u, class WHERE _id = LIMIT 1)WHERE EXISTS ( SELECT 1 FROM-- `user`, class WHERE _id = )结果表明:UPDATE语句的WHERE语句如果是EXISTS,那每执⾏⼀条就会判断⼀下,成⽴则执⾏SET语句 -- 类似于遍历执⾏。另外,UPDATE的表不能出现在FROM语句中。

这⾥的问题在于,EXISTS是bool判断,⽽SELECT则返回集合,容易让⼈⼀头雾⽔。

其实⽤PLSQL来写,逻辑更清晰⼀些。这⾥放上⼀个Oracle的PLSQL吧 -- MySQL的语法略有不同,暂没查到~~-- 打开控制台输出set serveroutput on-- PLSQLDECLARE -- 设置光标 CURSOR c is SELECT id,`name` FROM class; -- 定义光标变量 pid %type; pname %type;BEGIN -- 打开光标 OPEN c; LOOP -- 循环取出光标中的数据 FETCH c INTO pid,pname; -- 取出的数据放⼊变量中 EXIT WHEN c%notfound; -- 退出条件

-- 更新数据 UPDATE `user` SET `user`.class_name = pname WHERE `user`.class_id = pid; END LOOP; CLOSE c; -- 对于ORACLE,默认的事务隔离级别是 read committed。所以需要commit COMMIT;-- dbms__line('涨薪完毕'); -- 控制台输出完成提⽰END;/ -- 执⾏