SQL 更新

await db.update(users)
  .set({ name: 'Mr. Dan' })
  .where(eq(users.name, 'Dan'));

传递给 update 的对象应具有与数据库架构中的列名相匹配的键。 对象中值为 undefined 的键会被忽略:要将列设置为 null,请传递 null。 您可以将 SQL 作为值传递,以在更新对象中使用,如下所示:

await db.update(users)
  .set({ updatedAt: sql`NOW()` })
  .where(eq(users.name, 'Dan'));

限制

PostgreSQL
MySQL
SQLite
SingleStore
MSSQL
CockroachDB

使用 .limit()limit 子句添加到查询中 - 例如:

await db.update(usersTable).set({ verified: true }).limit(2);
update "users" set "verified" = $1 limit $2;

排序

使用 .orderBy() 向查询添加 order by 子句,按指定字段对结果进行排序:

import { asc, desc } from 'drizzle-orm';

await db.update(usersTable).set({ verified: true }).orderBy(usersTable.name);
await db.update(usersTable).set({ verified: true }).orderBy(desc(usersTable.name));

// 根据多个字段排序
await db.update(usersTable).set({ verified: true }).orderBy(usersTable.name, usersTable.name2);
await db.update(usersTable).set({ verified: true }).orderBy(asc(usersTable.name), desc(usersTable.name2));
update "users" set "verified" = $1 order by "name";
update "users" set "verified" = $1 order by "name" desc;

update "users" set "verified" = $1 order by "name", "name2";
update "users" set "verified" = $1 order by "name" asc, "name2" desc;

带返回值的更新

PostgreSQL
SQLite
MySQL
SingleStore
MSSQL
CockroachDB

您可以在 PostgreSQL 和 SQLite 中更新行并返回它:

const updatedUserId: { updatedId: number }[] = await db.update(users)
  .set({ name: 'Mr. Dan' })
  .where(eq(users.name, 'Dan'))
  .returning({ updatedId: users.id });

输出

MSSQL

您可以更新行并同时获取更新前和更新后的数据:

type User = typeof users.$inferSelect;

const updatedUserId: User[] = await db.update(users)
  .set({ name: 'Mr. Dan' })
  .where(eq(users.name, 'Dan'))
  .output();

返回更新后的部分用户字段:

const updatedUserId: { inserted: { updatedId: number }}[] = await db.update(users)
  .set({ name: 'Mr. Dan' })
  .where(eq(users.name, 'Dan'))
  .output({ inserted: { updatedId: users.id }});

返回更新前数据库中的行:

type User = typeof users.$inferSelect;

const updatedUserId: { deleted: User }[] = await db.update(users)
  .set({ name: 'Mr. Dan' })
  .where(eq(users.name, 'Dan'))
  .output({ deleted: true });

同时返回更新前和更新后的数据:

type User = typeof users.$inferSelect;

const updatedUserId: { deleted: User, inserted: User }[] = await db.update(users)
  .set({ name: 'Mr. Dan' })
  .where(eq(users.name, 'Dan'))
  .output({ deleted: true, inserted: true });

with update子句

查看如何在 selectinsertdelete 中使用 WITH 语句

使用 with 子句可以通过将复杂查询拆分为称为公共表表达式 (CTE) 的较小子查询来简化查询:

const averagePrice = db.$with('average_price').as(
        db.select({ value: sql`avg(${products.price})`.as('value') }).from(products)
);

const result = await db.with(averagePrice)
		.update(products)
		.set({
			cheap: true
		})
		.where(lt(products.price, sql`(select * from ${averagePrice})`))
		.returning({
			id: products.id
		});
with "average_price" as (select avg("price") as "value" from "products") 
update "products" set "cheap" = $1 
where "products"."price" < (select * from "average_price") 
returning "id"

Update … from

PostgreSQL
MySQL
SQLite
SingleStore
MSSQL
CockroachDB

正如 SQLite 文档所述:

UPDATE-FROM 是 SQL 的一个扩展,允许更新语句通过数据库中的其他表来驱动。 “目标”表是被更新的特定表。使用 UPDATE-FROM,您可以在目标表 和数据库中的其他表之间进行连接,以帮助计算哪些行需要更新以及 这些行的新值应该是什么。

PostgreSQL 文档同样指出:

允许在 WHERE 条件和更新表达式中出现其他表的列的表表达式。

Drizzle 从版本 drizzle-orm@0.36.3 起也支持此功能。

await db
  .update(users)
  .set({ cityId: cities.id })
  .from(cities)
  .where(and(eq(cities.name, 'Seattle'), eq(users.name, 'John')))
update "users" set "city_id" = "cities"."id" 
from "cities" 
where ("cities"."name" = $1 and "users"."name" = $2)

-- params: [ 'Seattle', 'John' ]

您还可以为连接的表指定别名(在 PostgreSQL 中,也可以为更新的表指定别名)。

const c = alias(cities, 'c');
await db
  .update(users)
  .set({ cityId: c.id })
  .from(c);
update "users" set "city_id" = "c"."id" 
from "cities" "c"
PostgreSQL
MySQL
SQLite
SingleStore
MSSQL
CockroachDB

在 PostgreSQL 中,您还可以返回连接表中的列。

const updatedUsers = await db
  .update(users)
  .set({ cityId: cities.id })
  .from(cities)
  .returning({ id: users.id, cityName: cities.name });
update "users" set "city_id" = "cities"."id" 
from "cities" 
returning "users"."id", "cities"."name"