当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 ...
随机推荐
- angular学习笔记(三十)-指令(3)-templateUrl
这篇主要介绍指令中的templateUrl属性: templateUrl属性值是一个url路径,路径指向一个html模板,html模板会填充(或替换)指令内容: 比如上一篇文章里的案例,我们把原来的t ...
- 使用canvas绘制饼状图
<!doctype html><html lang="en"><head> <meta charset="UTF-8" ...
- LeetCode: Minimum Path Sum 解题报告
Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to b ...
- 2017年研究生数学建模竞赛-E题 MATLAB 作战区域道路示意图
MATLAB 画区域作战图 clear load('output_path1.mat') k = 1:130; gplot(edge(k,k),loc(k,:),'c-') title('作战区域道路 ...
- RedHat下安装Python开发环境
Linux RedHat下安装Python2.7.pip.ipython环境.eclipse和PyDev环境 准备工作,源Python2.6备份: 根据which python具体目录而定,进行备份 ...
- java 多线程 24 : 线程组
线程组 可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的组织结构有点类似于树的形式,如图所示: 线程组的作用是:可以批量管理线程或线程组对象,有效地对线 ...
- MAMP和WAMP搭建Web环境,数据库,数据分布可视化
MAMP和WAMP搭建Web环境,数据库,数据分布可视化 1. 数据库 用MAMP和WAMP搭建Web环境,数据分布可视化 Web环境Web服务器:Apache.Nginx,处理Web请求数据库:My ...
- error "OPatch cannot find a valid oraInst.loc file to locate Central Inventory
Error tersebut terjadi ketika akan menjalankan command opatch lsinventory untuk mengetahui patch yan ...
- 在IIS中访问APS页面时提示:“最可能的原因使用的托管的处理程序,但是未安装或未完整安装asp.net“
打开CMD窗口,执行下面的命令: "%WINDIR%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe" -iru -ena ...
- 【Linux/CentOS】上手常见问题笔记
场景:Web项目服务端想要运行在Linux系统上,还要编写一些自动化发布代码的Shell脚本,需要学习使用Linux系统. 环境:Windows系统下用虚拟机VMware Workstation Pr ...