关于 UPDATE 语句 
=================================



UPDATE语句用来更新表的行记录。

简单的UPDATE语句语法格式如下：

```javascript
UPDATE table_name
SET column_name = value [, column_name = value]...
[ WHERE condition ];
```



其中，column_name 是要更新的列，等号后面的 value 是要更新的目标值，必须符合列的类型定义。WHERE 条件子句指定要更新的行记录必须满足的条件，没有 WHERE 条件子句就是更新表对应列的所有记录。

示例：更新所有记录 
------------------

```javascript
obclient> update t_insert set value=value+1 ;
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4  Changed: 4  Warnings: 0

obclient> select * from t_insert;
+----+------+-------+---------------------+
| id | name | value | gmt_create          |
+----+------+-------+---------------------+
|  1 | CN   | 10002 | 2020-04-03 17:18:06 |
|  2 | US   | 10003 | 2020-04-03 17:18:47 |
|  3 | EN   | 10004 | 2020-04-03 17:18:47 |
|  4 | JP   | 10005 | 2020-04-03 17:28:21 |
+----+------+-------+---------------------+
4 rows in set (0.00 sec)
```



不带条件更新的时候，如果记录数达到几十万或者几百万，会有大事务产生，可能会失败。所以 UPDATE 要注意控制事务不要太大。

示例：更新部分记录，违反约束报错 
-------------------------

```javascript
obclient> create unique index uk_name on t_insert(name);
Query OK, 0 rows affected (1.99 sec)

obclient> update t_insert set name='US' where id=3;
ERROR 1062 (23000): Duplicate entry 'US' for key 'uk_name'
```



除了显式的 UPDATE 语句外，还有几类语句也可以更新数据。比如说 INSERT 因为约束冲突失败的时候，可以使用 ON DUPCLICATE KEY UPDATE 子句转变为 UPDATE 语句更新相关字段。

#### 关于 INSERT ON DUPLICATE KEY UPDATE 子句 

使用 ON DUPLICATE KEY UPDATE 子句时，要求表上面要有主键或唯一约束（索引）。

**示例：使用** **INSERT ON DUPLICATE KEY UPDATE** **避免数据插入冲突** 

```javascript
obclient> INSERT INTO t_insert(id, name, value) VALUES (3,'UK', 10003);
ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY'

obclient> INSERT INTO t_insert(id, name, value) VALUES (3,'UK', 10003)
  ON DUPLICATE KEY UPDATE name='UK', value=10003 ;
Query OK, 2 rows affected (0.01 sec)

obclient> select * from t_insert;
+----+------+-------+---------------------+
| id | name | value | gmt_create          |
+----+------+-------+---------------------+
|  1 | CN   | 10002 | 2020-04-03 18:05:45 |
|  2 | US   | 10003 | 2020-04-03 18:05:54 |
|  3 | UK   | 10003 | 2020-04-03 18:05:54 |
|  4 | JP   | 10005 | 2020-04-03 18:06:08 |
+----+------+-------+---------------------+
4 rows in set (0.00 sec)
```



#### 关于 SELECT ... FOR UPDATE 子句 

使用 SELECT ... FOR UPDATE 可以在读取记录的时候就对记录加锁，避免其他 DML 语句对该笔记录进行同时修改，这种设计通常也称为"悲观锁策略"。

**示例：使用** **SELECT ... FOR UPDATE 先锁定记录后修改** 

```javascript
obclient> select id,name,value from t_insert where id=2 for update;
+----+------+-------+
| id | name | value |
+----+------+-------+
|  2 | US   | 10003 |
+----+------+-------+
1 row in set (0.01 sec)

obclient> update t_insert set value=value+100 where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
```


