当SQL UPDATE遇到EXISTS(SELECT ...)时
直接上例子。
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 ...)时的更多相关文章
- SQL Server判断对象是否存在 (if exists (select * from sysobjects )(转)
1 判断数据库是否存在Sql代码 if exists (select * from sys.databases where name = ’数据库名’) drop database [数据库名] ...
- SQL Server IF Exists 判断数据库对象是否存在的用法
1 判断数据库是否存在Sql代码 if exists (select * from sys.databases where name = ’数据库名’) drop database [数据库名] ...
- SQL update select
SQL update select语句 最常用的update语法是: UPDATE TABLE_NAME SET column_name1 = VALUE WHRER column_name2 = V ...
- SQL update select语句
SQL update select语句 最常用的update语法是:UPDATE <table_name>SET <column_name1> = <value>, ...
- 如何在PL/SQL Developer 中设置 在select时 显示所有的数据
在执行select 时, 总是不显示所有的记录, 要点一下, 下面那个按钮才会显示所有的数据. 解决方法: Tools>Preferences>Window Types>SQ ...
- select 时进行update的操作,在高并发下引起死锁
场景:当用户查看帖子详情时,把帖子的阅读量:ReadCount+1 select title,content,readcount from post where id='xxxx' --根据主键查 ...
- SQL exists( select 1 from
use UnlockIndustry select * from Info_Coordinate as A join Info_Employee on A.EmployeeId=Info_Employ ...
- MS SQL 当记录不存在时插入insert INTO not exists
INSERT INTO dbo.[T_DabaoTemp] ([PType] ,[pID] ,[NewVersion] ,[ParentC ...
- sql子查询 嵌套SELECT语句
嵌套SELECT语句也叫子查询,一个 SELECT 语句的查询结果能够作为另一个语句的输入值.子查询不但能够出现在Where子句中,也能够出现在from子句中,作为一个临时表使用,也能够出现在sele ...
随机推荐
- Spanner_
https://en.wikipedia.org/wiki/Spanner_(database) http://static.googleusercontent.com/media/research. ...
- c++ STL map 结构体
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候 ...
- Window 分布式 学习2----好文收藏
概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效 ...
- [DIOCP3-IocpTask说明书]基于IOCP引擎的多线程任务的投递和回调处理单元
[说明] IocpTask是基于Iocp引擎的多线程任务投递和处理单元,可以方便的把任务进行投递到IOCP线程进行统一调度和处理,是模仿QDAC-QWorker的处理方式,支持D7以上的版本. [使用 ...
- ctrl+z的ascii码是多少?
今天在使用中移动的模组的时候,发现: 突然把我难住了,ctrl+z要在我的数据包中通过TCP/IP发送,而结束字符肯定是需要我自己加在数据包的末尾的. 故,做如下测试: #include <st ...
- Android 自动化测试
Python +Android +uiautomator test 在init中定义的方法 uiautomator 该模块是android的一个python包装uiautomator测试框架 ...
- JAVA-数据库之查询记录
相关资料:<21天学通Java Web开发> ResultSet结果集1.使用exectteQuery()方法查询数据.2.exectueQuery()方法接收一个查询SQL语句.3.返回 ...
- Node.js学习笔记(6)--异步变同步
说明(2017-5-3 14:59:03): 1. 异步变同步: var fs = require("fs"); var documents = []; fs.readdir(&q ...
- angular 兼容ie7 bootstrap2兼容ie6
http://stackoverflow.com/questions/12709745/angular-routing-not-working-in-ie7/12891208#12891208
- 【转】 Java中的变量赋值和参数传递
原文地址:http://blog.csdn.net/whmii/article/details/3363667 变量赋值和参数传递是java中两个容易让人迷惑的问题.对于原始类型(primitives ...