精华内容
下载资源
问答
  • 原因:[HY000][1093] You can't specify target table 'eks_t1' for update in FROM clause 改成: delete from eks_t1 where id = (select * from (select id from eks_t1 order by age asc limit 1) a);...

    假设一张表,数据如下

    要求:删除年龄最小的记录

    delete from eks_t1
    where id = (select id
                from eks_t1
                order by age asc
                limit 1);
    

    结果:执行失败。

    原因:[HY000][1093] You can't specify target table 'eks_t1' for update in FROM clause

    改成:

    
    delete from eks_t1
    where id = (select *
                from (select id
                      from eks_t1
                      order by age asc
                      limit 1) a);

    结果:删除成功。

    分析:mysql不能在同一表中查询的数据作为同一表的更新数据。目前只发现mysql有这个问题,需要在内存select外再包一层select作为中间表。

    示例一,关联子查询

    update eas_clazz t1 left join
      (
        select
          t2.clazz_id,
          t3.subject_id
        from eas_clazz_course t2 left join eas_course t3 on t2.course_id = t3.id) t5 on t1.id = t5.clazz_id
    set t1.subject_id = t5.subject_id , t1.update_date = now();
    展开全文
  • 以MySQL 的InnoDB 为例,预设的Tansaction isolation level 为REPEATABLE READ,在SELECT 的... FOR UPDATE这两种方式在事务(Transaction) 进行当中SELECT 到同一个数据表时,都必须等待其它事务数据被提交(Commi...

    以MySQL 的InnoDB 为例,预设的Tansaction isolation level 为REPEATABLE READ,在SELECT 的读取锁定主要分为两种方式:

    SELECT ... LOCK IN SHARE MODE SELECT ... FOR UPDATE

    这两种方式在事务(Transaction) 进行当中SELECT 到同一个数据表时,都必须等待其它事务数据被提交(Commit)后才会执行。而主要的不同在于LOCK IN SHARE MODE 在有一方事务要Update 同一个表单时很容易造成死锁 。

    简单的说,如果SELECT 后面若要UPDATE 同一个表单,最好使用SELECT ... UPDATE。

    举个例子: 假设商品表单products 内有一个存放商品数量的quantity ,在订单成立之前必须先确定quantity 商品数量是否足够(quantity>0) ,然后才把数量更新为1。

    不安全的做法:

    复制代码 代码如下:

    SELECT quantity FROM products WHERE id=3; UPDATE products SET quantity = 1 WHERE id=3;

    为什么不安全呢?

    少量的状况下或许不会有问题,但是大量的数据存取「铁定」会出问题。

    果我们需要在quantity>0 的情况下才能扣库存,假设程序在第一行SELECT 读到的quantity 是2

    ,看起来数字没有错,但是当MySQL 正准备要UPDATE 的时候,可能已经有人把库存扣成0 了,但是程序却浑然不知,将错就错的UPDATE

    下去了。

    因此必须透过的事务机制来确保读取及提交的数据都是正确的。

    于是我们在MySQL 就可以这样测试:

    复制代码 代码如下:

    SET AUTOCOMMIT=0; BEGIN WORK; SELECT quantity FROM products WHERE id=3 FOR UPDATE;

    此时products 数据中id=3 的数据被锁住(注3),其它事务必须等待此次事务 提交后才能执行

    SELECT * FROM products WHERE id=3 FOR UPDATE 如此可以确保quantity 在别的事务读到的数字是正确的。

    复制代码 代码如下:

    UPDATE products SET quantity = '1' WHERE id=3 ; COMMIT WORK;

    提交(Commit)写入数据库,products 解锁。

    注1: BEGIN/COMMIT 为事务的起始及结束点,可使用二个以上的MySQL Command 视窗来交互观察锁定的状况。

    注2: 在事务进行当中,只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据时会等待其它事务结束后才执行,一般SELECT ... 则不受此影响。

    注3: 由于InnoDB 预设为Row-level Lock,数据列的锁定可参考这篇。

    注4: InnoDB 表单尽量不要使用LOCK TABLES 指令,若情非得已要使用,请先看官方对于InnoDB 使用LOCK TABLES 的说明,以免造成系统经常发生死锁。

    MySQL SELECT ... FOR UPDATE 的Row Lock 与Table Lock

    上面介绍过SELECT ...

    FOR UPDATE 的用法,不过锁定(Lock)的数据是判别就得要注意一下了。由于InnoDB 预设是Row-Level

    Lock,所以只有「明确」的指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table

    Lock (将整个数据表单给锁住)。

    举个例子:

    假设有个表单products ,里面有id 跟name 二个栏位,id 是主键。

    例1: (明确指定主键,并且有此数据,row lock)

    复制代码 代码如下:

    SELECT * FROM products WHERE id='3' FOR UPDATE;

    例2: (明确指定主键,若查无此数据,无lock)

    复制代码 代码如下:

    SELECT * FROM products WHERE id='-1' FOR UPDATE;

    例2: (无主键,table lock)

    复制代码 代码如下:

    SELECT * FROM products WHERE name='Mouse' FOR UPDATE;

    例3: (主键不明确,table lock)

    复制代码 代码如下:

    SELECT * FROM products WHERE id<>'3' FOR UPDATE;

    例4: (主键不明确,table lock)

    复制代码 代码如下:

    SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;

    注1: FOR UPDATE 仅适用于InnoDB,且必须在事务区块(BEGIN/COMMIT)中才能生效。

    注2: 要测试锁定的状况,可以利用MySQL 的Command Mode ,开二个视窗来做测试。

    复制代码 代码如下:

    MySQL update && select

    CREATE TABLE `testupdate` (

    `id` bigint(20) NOT NULL AUTO_INCREMENT,

    `val` bigint(20) NOT NULL DEFAULT '0',

    PRIMARY KEY (`id`)

    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

    update testupdate

    set val = val+1

    where id = 1 and @value := val+1;

    select @value;

    原文:http://www.jb51.net/article/42778.htm

    展开全文
  • Oracle Select for update用法 通常情况下Select不会对资料加锁,不会影响其他Session执行DML和DDL,借助for update子句就可以实现对资料加锁保护操作。當只允許一個session進行update的時候, for update十分有用. ...

    Oracle Select for update用法

    通常情况下Select不会对资料加锁,不会影响其他Session执行DML和DDL,借助for update子句就可以实现对资料加锁保护操作。當只允許一個session進行update的時候, for update十分有用.
    在select … for update之后,可以使用of子句对select的特定资料进行加锁操作,不适用of子句表示在select所有的表加锁。
    select * from test for update; 會對table test進行加鎖. 此時只允許當前的session對已經存在的資料進行更新. 但其它session仍可以進行insert的操作,只是不允许进行update操作。

    select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update of a.pkid 只鎖定Table1中滿足條件的行, 這就是使用of子句的作用. 比較常用於多個表的操作.

    加入for update之後,Oracle就要求啟動一個新事務,嘗試對資料進行加鎖。如果當前已經被加鎖,預設的行為必然是block等待。使用nowait子句的作用就是避免進行等待,當發現請求加鎖資源被鎖定未釋放的時候,直接報錯返回。如果不使用nowait或wait子句, 新的加鎖請求會一直hang住, 直到原來的commit或rollback.

    select * from test where a=2 for update nowait;
    ERROR at line 1:
    ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

    或者
    select * from test where a=2 for update wait 3; 如果3秒內還是無法加鎖則返回錯誤.

    在一個session內可以多次進行select XX for update,然後只需要commit或rollback一次即可釋放.

    引用

    oracle for update和for update nowait的区别

    展开全文
  • 本文主要向大家介绍了MySQL update嵌套select问题,通过具体的实例让大家了解,希望对大家学习MySQL有所帮助。当你希望更新一批值,且值是通过select条件查询出来时,下面这个错误应该不陌生You can’t specify ...

    本文主要向大家介绍了MySQL update嵌套select问题,通过具体的实例让大家了解,希望对大家学习MySQL有所帮助。

    当你希望更新一批值,且值是通过select条件查询出来时,下面这个错误应该不陌生

    You can’t specify target table ‘x’ for update in FROM clause。

    错误示范 1: A B 有关联同一个key_id , 根据 B表符合条件 -> 更新A表val值。UPDATE A a SET a.val = 2

    WHERE a.id IN ( SELECT a.id FROM A

    LEFT JOIN B ON b.key_id = a.key_id

    WHERE b.satisfy = 1)

    解决思路 1: 使用 INNER JOIN (最简洁)UPDATE A a INNET JOIN B b ON b.key_id = a.key_id

    SET a.val = 2 WHERE b.satisfy = 1

    解决思路 2:UPDATE A a, (SELECT A.id from A

    LEFT JOIN B ON B.key_id= A.key_id

    WHERE B.satisfy = 1) b

    SET a.val = 2

    WHERE a.id = b.id

    本文由职坐标整理并发布,希望对同学们学习MySQL有所帮助,更多内容请关注职坐标数据库MySQL数据库频道!

    展开全文
  • 一、单表查询—>更新UPDATE table_nameSET field1=new-value1, field2=new-value2[WHERE ...更新UPDATE aINNER JOIN (SELECT yy FROM b) c ON a.id = c.idSET a.xx = c.yy[WHERE Clause]上面的 INNER JOIN ,可以...
  • UPDATE bx_well_device_group_device dgd LEFT JOIN ( SELECT enterprise_id, device_group_id,device_id FROM bx_well_device_group WHERE del_flag = '0' ) dg ON dg.device_group_id = dgd.device_group_id SET ...
  • 通常情况下,select语句是不会对数据加锁,不会妨碍影响其他的DML和DDL操作。...在select…for update之后,可以使用of子句选择对select的特定数据表进行加锁操作。默认情况下,不使用of子句表示在select所有的数...
  • 在MySQL的InnoDB中,预设的Tansaction isolation level为REPEATABLE READ(可重读)在SELECT的读取... FOR UPDATE这两种方式在事务(Transaction)进行当中SELECT到同一个数据表时,都必须等待其它事务数据被提交(Commi...
  • update t1 set (t1.LONGITUDE,t1.LATITUDE) = (select t.LATITUDE,t.LONGITUDE from GPSDATA t where t.LATITUDE > 100 AND t.GUID = t1.GUID)
  • updateselect连用 根据查询出来的条件进行更新 UPDATE tb_user A INNER JOIN ( SELECT phone, third_number FROM tb_relation ) C ON C.phone= A.user_code SET A.user_code = c.third_number, A.`password` = MD...
  • mysql中使用select for update的必须针对InnoDb,并且是在一个事务中,才能起作用。 select的条件不一样,采用的是行级锁还是表级锁也不一样。 由于 InnoDB 预设是 Row-Level Lock,所以只有「明确」的指定主键,...
  • I'm trying to understand MySQL Stored Procedures, I want to check if a users login credentials are valid and if so, update the users online status:-- DROP PROCEDURE IF EXISTS checkUser;DELIMITER //CRE...
  • SELECT ...for update是在MySQL悲观锁的应用, 何为MySQL的悲观锁(有悲观锁,就有乐观锁,下面一一介绍)? 悲观锁是对数据被修改时持悲观态度(认为数据在被修改的时候一定会存在并发问题),因此在整个数据处理...
  • mysql update select 用法

    2021-01-19 12:01:12
    之前用SqlServer , update语句对表进行更新:update a set a.xx= (select yy from b) ; 是可以的但是在mysql中,不能直接使用set select的结果,UPDATE ecs_users_copySET `user_name` = (SELECT`identity_card`...
  • QL update select语句最常用的update语法是:UPDATE SET = , SET = www.2cto.com如果我的更新值Value是从一条select语句拿出来,而且有很多列的话,用这种语法就很麻烦第一,要select出来放在临时变量上,有很多个...
  • plsql通过select…for update语句修改数据 1.登录plsql 2.点击这个白纸,选择 SQL窗口 3.写入sql,按F8或者黄色的齿轮按钮 4。查询出数据后,这时还是无法对数据进行操作的,需要点击图中的锁,就可以对数据操作了...
  • ——————————— Oracle —————————————————–Oracle 的for update行锁键字: oracle 的for update行锁SELECT…FOR UPDATE 语句的语法如下:SELECT … FOR UPDATE [OF column_list][WAIT n|NO...
  • Mysql 先SELECTUPDATE 问题

    千次阅读 2021-01-20 14:39:20
    其实这个应该是并发引起的,先selectupdate 这样写其实会出现一些问题###第一种解决方案事务,即用一个事务来包裹上面的SELECT+UPDATE操作+写共享锁。读共享锁是通过下面这样的SQL获得的:SELECT * FROM parent ...
  • +----+--------+------+ | id | status | name | +----+--------+------+ | 1 | 1 | 道具 | +----+--------+------+ console2:查询被阻塞 mysql> select * from goods where id=1 for update; console2:如果...
  • UPDATESELECT嵌套使用

    2021-01-25 12:07:45
    UVA 11168 Airport(凸包&plus;直线方程)题意:给你n[1,10000]个点,求出一条直线,让所有的点都在都在直线的一侧并且到直线的距离总和最小,输出最小平均值(最小值除以点数) 题解:根据题意可以知道任意角度画一条...
  • SELECT FOR UPDATE语句

    2021-01-19 09:54:19
    悲观锁实现:以下实例使用MySQL官方数据库sakila ...SELECT * FROM city WHERE city_id=1 FOR UPDATE; SELECT sleep(10); COMMIT; NOTE:只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 相同数据时会等待其它
  • UPDATE table1 SET column1 = (SELECT column FROM table2 [WHERE condition]) WHERE table1.column2 = value; 注:若不加where条件则是更新表中的所有数据, 故执行没有where子句的update要慎重再慎重。 第二种:...
  • eq: update a set a.x = 1 where a.y in (select a.x from a);上边语法是错误的,在对aupdate 时不能再条件中对同一个a表进行 select 操作如果非得要操作 那只能 把 条件中 再关联一次(不能的缘由是因为 条件中的...
  • 写了一个存储过程,把我数据库user2全部表批量赋值给user1, 而且具备对表的select、insert、delete、update权限。 存储过程以下: CREATE OR REPLACE PROCEDURE GRANT_MAHANSO AS CURSOR c_tablename IS SELECT ...
  • 近期有一个业务需求,多台机器需要同时从Mysql一个表里查询...解决同时拿数据的方法有很多,为了更加简单,不增加其他表和服务的情况下,我们考虑采用select... for update的方式,这样X锁锁住查询的数据段,表里...
  • 但是mysql不支持update set直接使用select的结果,那么怎么在mysql update中使用select的结果呢?我们可以换一种解决方法,也就是使用inner join,上面的sql语句在mysql中可以改写成下面方式:...
  • 作者: 弦乐之花 | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明mysql innodb之select for update nowait习惯了oracle数据库的select for update nowait的同学,如果转在mysql环境开发的话,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 953,875
精华内容 381,550
关键字:

selectupdate