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'));
Limit (제한)
.limit()
메서드를 사용하면 쿼리에 limit
절을 추가할 수 있습니다. 예를 들어:
await db.update(usersTable).set({ verified: true }).limit(2);
update "users" set "verified" = $1 limit $2;
위 예제에서는 users
테이블에서 verified
컬럼을 true
로 업데이트하는 쿼리에 limit 2
를 적용했습니다. 이는 최대 2개의 행만 업데이트하도록 제한합니다.
Order By
.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));
위 코드는 다음과 같은 SQL 쿼리로 변환됩니다.
-- 단일 필드로 정렬
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에서는 행을 업데이트하고 결과를 반환받을 수 있습니다:
const updatedUserId: { updatedId: number }[] = await db.update(users)
.set({ name: 'Mr. Dan' })
.where(eq(users.name, 'Dan'))
.returning({ updatedId: users.id });
with update
절
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
SQLite 문서에 따르면:
UPDATE-FROM은 SQL의 확장 기능으로, 데이터베이스의 다른 테이블을 기반으로 UPDATE 문을 실행할 수 있게 해줍니다. “대상” 테이블은 업데이트할 특정 테이블을 의미합니다. 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에서는 조인된 테이블의 컬럼을 반환할 수도 있습니다.
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"