博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
当SQL UPDATE遇到EXISTS(SELECT ...)时
阅读量:7246 次
发布时间:2019-06-29

本文共 2651 字,大约阅读时间需要 8 分钟。

直接上例子。

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` uSET 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-- PLSQLDECLARE    -- 设置光标    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;/   -- 执行

转载地址:http://mjnbm.baihongyu.com/

你可能感兴趣的文章
vue一些基础知识
查看>>
百度编辑器editor的使用
查看>>
js 预编译 解释执行 作用域链 闭包
查看>>
Django-CSRF的使用
查看>>
Python数据库连接池DBUtils(基于pymysql模块连接数据库)
查看>>
nodejs+express安装
查看>>
Android Studio提示 Connection reset
查看>>
java反射
查看>>
usb mass storage device
查看>>
XAML实例教程系列 - 类型转换器(Type Converter)
查看>>
LINQ 关键字
查看>>
nodejs gyp WARN EACCES user "root" does not have permission to access the dev dir
查看>>
Apache + PHP
查看>>
实现表格tbody内滚动
查看>>
jdbc链接数据库
查看>>
git 分支管理
查看>>
【高效程序员系列】目录
查看>>
JS中循环逻辑和判断逻辑的使用实例
查看>>
从零开始开发一个简易的类vue-cli构建工具
查看>>
中国工业软件成立联盟合力对外
查看>>