在上一篇文章中介绍了应用开发人员在开发数据库访问逻辑时最频繁使用DML语句的用法和示例,包括:INSERT、UPDATE、DELETE和SELECT等语句。这篇文章将向大家介绍UPSERT、WITH等语句的用法。
1. UPSERT语句
在CRDB中,UPSERT语句是“精简版的”INSERT ON CONFLICT(前一篇文章有描述)。当待插入行中的值没有违反表的主键约束时,插入这个记录;如果违背了,那么就更新相应的记录。下面我们结合一些示例进行说明:
(1) UPSERT单行(没有主键冲突)
在CRDB中,可以使用UPSERT语句向一个表插入或更新数据。例如:
CREATE TABLE accounts(
id INT PRIMARY KEY ,
name VARCHAR(30),
balance DECIMAL(15,2)
);
UPSERT INTO accounts VALUES (1, 'user11', 1000.25);
UPSERT INTO accounts VALUES (2, 'user22', 2000.75);
SELECT * FROM accounts;
如下图所示:
创建完表之后,由于还有记录,所以执行上面的两条UPSERT语句都是插入记录到表中。
(2) UPSERT单行(有主键冲突)
例如:
UPSERT INTO accounts VALUES (2,'user22',3500.10);
SELECT * FROM accounts;
如下图所示:
由于上面的UPSERT语句插入的记录(id=2)已经存在,所以对存在记录进行更新。
(3) UPSERT多行(没有主键冲突)
例如:
UPSERT INTO accounts VALUES (3,'user33',3500.10),(4,'user44',4000.35);
SELECT * FROM accounts;
如下图所示:
(4) UPSERT 多行(有主键冲突)
我们看如下的例子:
UPSERT INTO accounts VALUES (4,'user44',3500.10) , (5,'user55',4800.35);
SELECT * FROM accounts ;
输出如下图所示:
2. 使用WITH定义公共Table表达式
从CRDB 2.0版本开始支持“Common Table Expressions”(简称CTE),CTE能够为一个复杂的查询定义一个别名,然后可以在查询语句中使用。我们还是通过例子来进行说明:
WITH o AS (SELECT * FROM orders WHERE id IN (33, 542, 112))
SELECT *
FROM customers AS c, o
WHERE o.customer_id = c.id;
上面的语句与如下的语句等价,但是使用WITH 定义CTE更容易阅读,特别是对于比较复杂的查询语句:
SELECT *
FROM customers AS c, ( SELECT * FROM orders WHERE id IN (33, 542, 112) ) AS o
WHERE o.customer_id = c.id;
参考:
https://www.cockroachlabs.com/docs/stable/upsert.html
https://www.cockroachlabs.com/docs/stable/common-table-expressions.html