> * 原文地址：[What's new in SQLite 3.35](https://nalgeon.github.io/sqlite-3-35/)
> * 原文作者：[Anton Zhiyanov](https://antonz.org/)
> * 译文出自：[掘金翻译计划](https://github.com/xitu/gold-miner)
> * 本文永久链接：[https://github.com/xitu/gold-miner/blob/master/article/2021/whats-new-in-sqlite-3-35.md](https://github.com/xitu/gold-miner/blob/master/article/2021/whats-new-in-sqlite-3-35.md)
> * 译者：[霜羽 Hoarfroster](https://github.com/PassionPenguin)
> * 校对者：[kamly](https://github.com/kamly)

# SQLite 3.35 版本有什么新的东西？

SQLite 开发者通常更喜欢实现数据库的核心组件，而对于外部观察者来说，什么都没有真正的改变。2020 年是一个令人愉快的例外 —— SQLite 为普通用户提供了许多不错的功能，例如自动生成列，`UPDATE FROM` 以及 Shell 中 `.mode box` 这个出色的功能。

2021 年极有可能延续这一风格，以下是 3.35 版本中提供的内容：

* 添加了内置的 SQL 数学函数 ‼️️
* 增加了对 `ALTER TABLE DROP COLUMN` 的支持 ❗
* 在 `DELETE`、`INSERT` 和 `UPDATE` 语句上添加对 `RETURNING` 子句的支持。
* 支持 CTE 公用表表达式 `MATERIALIZED` 和 `NOT_MATERIALIZED` 提示。

以下是有关每个功能的一些详细信息。

## 数学函数

多年以来，大量用户都上书，恳求 SQLite 的开发者加入数学基本函数，如 `sqrt()`、`log()` 和 `pow()`。而获得的答复总是差不多：

> SQLite 之所以被称为 Lite 是有原因的。如果你需要这些函数，请自己添加。

这确实是一个可以理解的立场。但是拒绝添加平方根？但是却又同时实现窗口函数、递归查询和其他高级 SQL 功能吗？你认真的吗？

也许 SQLite 开发人员更喜欢专注于大客户愿意花钱购买的功能。无论如何，在等待 20 年后，我们现在终于可以使用数学函数了！

以下是支持的函数的完整列表：

```sql
acos(X)
acosh(X)
asin(X)
asinh(X)
atan(X)
atan2(X,Y)
ceil(X)
ceiling(X)
cos(X)
cosh(X)
degrees(X)
exp(X)
floor(X)
ln(X)
log(B,X)
log(X)
log10(X)
log2(X)
mod(X,Y)
pi()
pow(X,Y)
power(X,Y)
radians(X)
sin(X)
sinh(X)
sqrt(X)
tan(X)
tanh(X)
trunc(X)
```

## 移除 Column

可能是用户苦难的第二大来源。我们可以自由地创建任意数量的列，但是无法删除它们，令人实在感到不快。你说要要删除列？先复制一份没有这个列的表的副本，然后删除旧表。

现在，这种痛苦终于消失了！`ALTER TABLE DROP COLUMN`，我们等你等得好苦啊。

不过要删除列，SQLite 必须完全重写表内容 —— 因此操作并不快速。当然绝对还是好过没有这个功能！

## RETURNING 语句

`DELETE`、`INSERT` 和 `UPDATE` 的查询语句现在支持返回他们删除，添加，或分别改变的行。

例如，返回新记录的 `id`：

```sql
create table users (
  id integer primary key,
  first_name text,
  last_name text
);

insert into users (first_name, last_name)
values ('Jane', 'Doe')
returning id;
```

或返回一个涨价的商品：

```sql
update products set price = price 1.10
where price <= 99.99
returning name, price as new_price;
```

## Materialized 的 CTE 公用表表达式

CTE（公用表表达式）是使查询更具表现力的好方法。例如，计算每个世纪建立的城市数量：

```sql
create table city(
  city text,
  timezone text,
  geo_lat real,
  geo_lon real,
  population integer,
  foundation_year integer
);

-- insert data ...

with history as (
  select
    city,
    (foundation_year/100)+1 as century
  from city
)
select
  century || ' century' as dates,
  count(*) as city_count
from history
group by century
order by century desc;
```

如果同一条 CTE 语句在查询中出现多次，则 SQLite 会多次计算该 CTE。对于比较大的表，这个操作可能会很缓慢。

而对于实例化的 CTE，SQLite 则只会执行一次查询，然后会记下结果，并且在同一查询中不会重新计算：

```sql
with history as materialized (
  select ...
)
select ... from history where ...
except
select ... from history where ...
;
```

四大功能，一次满足，真的太棒了！

[SQLite 3.35.0 发行公告（草案）](https://sqlite.org/releaselog/3_35_0.html) ｜ [下载 SQLite 最新版本](https://sqlite.org/download.html)

> 如果发现译文存在错误或其他需要改进的地方，欢迎到 [掘金翻译计划](https://github.com/xitu/gold-miner) 对译文进行修改并 PR，也可获得相应奖励积分。文章开头的 **本文永久链接** 即为本文在 GitHub 上的 MarkDown 链接。

---

> [掘金翻译计划](https://github.com/xitu/gold-miner) 是一个翻译优质互联网技术文章的社区，文章来源为 [掘金](https://juejin.im) 上的英文分享文章。内容覆盖 [Android](https://github.com/xitu/gold-miner#android)、[iOS](https://github.com/xitu/gold-miner#ios)、[前端](https://github.com/xitu/gold-miner#前端)、[后端](https://github.com/xitu/gold-miner#后端)、[区块链](https://github.com/xitu/gold-miner#区块链)、[产品](https://github.com/xitu/gold-miner#产品)、[设计](https://github.com/xitu/gold-miner#设计)、[人工智能](https://github.com/xitu/gold-miner#人工智能)等领域，想要查看更多优质译文请持续关注 [掘金翻译计划](https://github.com/xitu/gold-miner)、[官方微博](http://weibo.com/juejinfanyi)、[知乎专栏](https://zhuanlan.zhihu.com/juejinfanyi)。
