SQL 업데이트

SQL 업데이트

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

set()에 전달하는 객체는 데이터베이스 스키마의 컬럼명과 일치하는 키를 가져야 합니다. undefined 값은 객체에서 무시됩니다. 컬럼을 null로 설정하려면 null을 전달하세요. 다음과 같이 SQL 표현식을 값으로 전달하여 업데이트 객체에 사용할 수 있습니다:

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

Limit

PostgreSQL
MySQL
SQLite
SingleStore
MSSQL
CockroachDB

.limit()을 사용하여 쿼리에 limit 절을 추가할 수 있습니다:

await db.update(usersTable).set({ verified: true }).limit(2);
update "users" set "verified" = $1 limit $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));
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;

반환 (Returning)

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 });

출력 (Output)

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 절을 사용한 업데이트

WITH 문을 사용하는 방법은 select, insert, delete에서도 확인할 수 있습니다.

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은 UPDATE 문이 데이터베이스의 다른 테이블을 활용할 수 있도록 하는 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"