直接上例子。

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查询class.name,并用其更新`user`.class_name。

注意:这里测试的是UPDATE 语句与 WHERE EXISTS 语句的执行顺序,所以请忽略表设计方面的问题吧。

语句如下:

UPDATE `user` u
SET u.class_name = (
SELECT
class.`name`
FROM
-- `user` u,
class
WHERE
u.class_id = class.id LIMIT 1
)
WHERE
EXISTS (
SELECT
1
FROM
-- `user`,
class
WHERE
u.class_id = class.id
)

结果表明:

UPDATE语句的WHERE语句如果是EXISTS,那每执行一条就会判断一下,成立则执行SET语句 -- 类似于遍历执行。
另外,UPDATE的表不能出现在FROM语句中。

这里的问题在于,EXISTS是bool判断,而SELECT则返回集合,容易让人一头雾水。

其实用PLSQL来写,逻辑更清晰一些。这里放上一个Oracle的PLSQL吧 -- MySQL的语法略有不同,暂没查到~~

-- 打开控制台输出
set serveroutput on
-- PLSQL
DECLARE
-- 设置光标
CURSOR c is SELECT id,`name` FROM class;
-- 定义光标变量
pid class.id%type;
pname class.name%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_output.put_line('涨薪完毕'); -- 控制台输出完成提示
END;
/ -- 执行

最新文章

  1. 深入理解DOM事件类型系列第二篇——键盘事件
  2. Servlet 之 HttpServlet
  3. QTP参数化
  4. 记录容易忘记的知识点(html 内容)
  5. CentOS安装apache2(转载)
  6. DELPHI下的SOCK编程(转)
  7. SAS、R以及SPSS的比较__统计语言大战
  8. 你们都是怎么阅读android系统源码的,用什么工具?
  9. winform 窗体大小变化时,如何设置使控件一起按照比例变大
  10. uva 1151 - Buy or Build poj 2784 Buy or Build(最小生成树)
  11. swift 新功能介绍
  12. 【甘道夫】Apache Hadoop 2.5.0-cdh5.2.0 HDFS Quotas 配额控制
  13. 转载--C# PLINQ 内存列表查询优化历程
  14. linux软件包介绍
  15. java.lang.String中[ "张飞"+1+1 ] 和 [ "张飞"+(1+1) ]
  16. 机器学习实践之Logistic回归
  17. Python中and(逻辑与)计算法则
  18. nginx+fastCGI
  19. DataGridView设置行高
  20. spring事务详解(四)测试验证

热门文章

  1. 【Android】ADB常用指令与logcat日志
  2. 【嵌入式】FS2410非操作系统外围资源测试
  3. 显示eclipse中Problem窗口的方法
  4. 使用jQuery清空file文件域的解决方案
  5. Android padding 和margin
  6. poj1733(区间上的种类并查集)
  7. Delphi中的三目运算函数有哪些?(XE10.2+WIN764)
  8. Android Studio SVN使用
  9. 2017 码云最火爆开源项目 TOP 50,你都用过哪些
  10. 【WPF】右键菜单ContextMenu可点击区域太小的问题