SQL 更新

传递给 .set() 的所有值都会自动参数化。 例如,这个查询:

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

将会被翻译为:

update "users" set "name" = $1 where "users"."name" = $2; -- params: ['Mr. Dan', 'Dan']

你传递给 update 的对象应当包含与你数据库模式中的列名相匹配的键。 对象中的 undefined 值会被忽略:如果要将某一列设为 null,请传入 null

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

你可以将 SQL 作为值传入更新对象中,例如:

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

返回

你可以在 CockroachDB 中更新一行并将其取回:

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

with update 子句

查看如何将 WITH 语句与 selectinsertdelete 一起使用

使用 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" = true 
where "products"."price" < (select * from "average_price") 
returning "id"

从 … 更新

正如 CockroachDB 文档所述:

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

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" = 'Seattle') and ("users"."name" = 'John'))

你也可以为连接的表起别名(更新表本身也可以起别名)。

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"

在 Postgres 中,你还可以返回连接表中的列。

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"