直接上例子。

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;
/ -- 执行

当SQL UPDATE遇到EXISTS(SELECT ...)时的更多相关文章

  1. SQL Server判断对象是否存在 (if exists (select * from sysobjects )(转)

    1 判断数据库是否存在Sql代码 if exists (select * from sys.databases where name = ’数据库名’)    drop database [数据库名] ...

  2. SQL Server IF Exists 判断数据库对象是否存在的用法

    1 判断数据库是否存在Sql代码 if exists (select * from sys.databases where name = ’数据库名’)    drop database [数据库名] ...

  3. SQL update select

    SQL update select语句 最常用的update语法是: UPDATE TABLE_NAME SET column_name1 = VALUE WHRER column_name2 = V ...

  4. SQL update select语句

    SQL update select语句 最常用的update语法是:UPDATE <table_name>SET <column_name1> = <value>, ...

  5. 如何在PL/SQL Developer 中设置 在select时 显示所有的数据

    在执行select 时, 总是不显示所有的记录, 要点一下, 下面那个按钮才会显示所有的数据.     解决方法: Tools>Preferences>Window Types>SQ ...

  6. select 时进行update的操作,在高并发下引起死锁

    场景:当用户查看帖子详情时,把帖子的阅读量:ReadCount+1 select title,content,readcount from post where id='xxxx'   --根据主键查 ...

  7. SQL exists( select 1 from

    use UnlockIndustry select * from Info_Coordinate as A join Info_Employee on A.EmployeeId=Info_Employ ...

  8. MS SQL 当记录不存在时插入insert INTO not exists

    INSERT INTO dbo.[T_DabaoTemp]  ([PType]           ,[pID]           ,[NewVersion]           ,[ParentC ...

  9. sql子查询 嵌套SELECT语句

    嵌套SELECT语句也叫子查询,一个 SELECT 语句的查询结果能够作为另一个语句的输入值.子查询不但能够出现在Where子句中,也能够出现在from子句中,作为一个临时表使用,也能够出现在sele ...

随机推荐

  1. Spanner_

    https://en.wikipedia.org/wiki/Spanner_(database) http://static.googleusercontent.com/media/research. ...

  2. c++ STL map 结构体

    Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候 ...

  3. Window 分布式 学习2----好文收藏

    概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效 ...

  4. [DIOCP3-IocpTask说明书]基于IOCP引擎的多线程任务的投递和回调处理单元

    [说明] IocpTask是基于Iocp引擎的多线程任务投递和处理单元,可以方便的把任务进行投递到IOCP线程进行统一调度和处理,是模仿QDAC-QWorker的处理方式,支持D7以上的版本. [使用 ...

  5. ctrl+z的ascii码是多少?

    今天在使用中移动的模组的时候,发现: 突然把我难住了,ctrl+z要在我的数据包中通过TCP/IP发送,而结束字符肯定是需要我自己加在数据包的末尾的. 故,做如下测试: #include <st ...

  6. Android 自动化测试

    Python +Android +uiautomator test  在init中定义的方法 uiautomator     该模块是android的一个python包装uiautomator测试框架 ...

  7. JAVA-数据库之查询记录

    相关资料:<21天学通Java Web开发> ResultSet结果集1.使用exectteQuery()方法查询数据.2.exectueQuery()方法接收一个查询SQL语句.3.返回 ...

  8. Node.js学习笔记(6)--异步变同步

    说明(2017-5-3 14:59:03): 1. 异步变同步: var fs = require("fs"); var documents = []; fs.readdir(&q ...

  9. angular 兼容ie7 bootstrap2兼容ie6

    http://stackoverflow.com/questions/12709745/angular-routing-not-working-in-ie7/12891208#12891208

  10. 【转】 Java中的变量赋值和参数传递

    原文地址:http://blog.csdn.net/whmii/article/details/3363667 变量赋值和参数传递是java中两个容易让人迷惑的问题.对于原始类型(primitives ...