UPDATE
테이블의 기존 행을 수정하는 UPDATE 문이에요. WHERE 조건으로 바꿀 행을 고르고, SET 절로 새 값을 지정하는 기본 구조만 익히면 대부분의 갱신 작업을 처리할 수 있어요.
출처: 문서
본문
UPDATE 문은 테이블의 기존 행에서 컬럼 값을 수정해요.
Syntax
UPDATE [OR conflict-algorithm] table-name
SET column-name = expression [, column-name = expression ...]
[FROM from-clause]
[WHERE expression]
[RETURNING result-column [, result-column ...]]
[ORDER BY sort-expression [, sort-expression ...]]
[LIMIT expression [OFFSET expression]]
Description
UPDATE는 WHERE 조건과 일치하는 행의 컬럼 값을 바꿔요. WHERE 절을 생략하면 테이블의 모든 행이 갱신돼요.
Conflict Handling
선택 사항인 OR 절은 갱신 중에 제약 조건 위반이 발생했을 때 어떻게 처리할지 지정해요. 생략하면 기본 동작은 ABORT예요.
| Algorithm | Behavior |
|---|---|
ABORT |
현재 문장을 롤백하고 오류를 돌려줘요. 트랜잭션은 활성 상태로 남아요. 이것이 기본값이에요. |
ROLLBACK |
트랜잭션 전체를 롤백하고 오류를 돌려줘요. |
FAIL |
첫 제약 조건 위반에서 멈추고 오류를 돌려주지만, 이 문장에서 앞선 행들이 만든 변경은 유지돼요. |
IGNORE |
제약 조건 위반을 일으킨 행은 건너뛰고 나머지 행 처리를 계속해요. |
REPLACE |
현재 행을 갱신하기 전에 충돌 행을 삭제해요. NOT NULL 제약이 실패했는데 DEFAULT 값이 없으면 문장은 ABORT처럼 동작해요. |
UPDATE OR IGNORE employees
SET department = 'Engineering'
WHERE department = 'IT';
SET Clause
SET 절은 하나 이상의 컬럼에 새 값을 할당해요. 각 할당은 컬럼 이름, 등호, 표현식으로 이루어져요. 표현식은 같은 행의 다른 컬럼을 참조할 수 있고, 모든 컬럼의 원래(갱신 전) 값을 보게 돼요.
UPDATE products
SET price = price * 1.10,
updated_at = datetime('now');
괄호로 감싼 컬럼 목록을 사용해 여러 컬럼을 설정할 수도 있어요.
UPDATE products
SET (price, updated_at) = (price * 1.10, datetime('now'));
FROM Clause
FROM 절을 쓰면 UPDATE가 다른 테이블을 참조할 수 있어요. 조인된 테이블의 컬럼을 SET 표현식과 WHERE 절에서 사용할 수 있어요. 다른 테이블의 일치하는 행을 기준으로 테이블을 갱신할 때 유용해요.
UPDATE inventory
SET quantity = inventory.quantity - order_items.qty
FROM order_items
WHERE inventory.product_id = order_items.product_id
AND order_items.order_id = 1001;
대상 테이블이 FROM 절에도 나타나면, 그 이름은 셀프 조인에 쓸 수 있는 해당 테이블의 두 번째 인스턴스를 가리켜요.
WHERE Clause
WHERE 절은 어떤 행을 갱신할지 제한해요. 표현식이 참으로 평가되는 행만 수정돼요. WHERE 절을 생략하면 테이블의 모든 행이 갱신돼요.
RETURNING Clause
RETURNING 절을 쓰면 UPDATE 문이 수정된 각 행의 새 값을 돌려줘요. 결과 컬럼에는 갱신된 컬럼 값을 참조하는 표현식을 쓸 수 있어요.
UPDATE accounts
SET balance = balance - 100
WHERE account_id = 42
RETURNING account_id, balance;
-- Returns: 42|900
ORDER BY and LIMIT
ORDER BY와 LIMIT 절은 갱신할 행을 제한해요. ORDER BY는 행을 고려하는 순서를 정하고, LIMIT은 실제로 수정되는 행 수를 제한해요. ORDER BY를 쓰려면 LIMIT이 반드시 있어야 해요.
UPDATE logs
SET archived = 1
ORDER BY created_at ASC
LIMIT 1000;
LIMIT은 선택적인 OFFSET을 받아서, 제한을 적용하기 전에 지정한 수만큼 행을 건너뛰게 해 줘요.
UPDATE logs
SET archived = 1
ORDER BY created_at ASC
LIMIT 1000 OFFSET 500;
Examples
Update rows matching a condition
CREATE TABLE employees (id INTEGER PRIMARY KEY, name TEXT, salary REAL, department TEXT);
INSERT INTO employees VALUES (1, 'Alice', 90000, 'Engineering');
INSERT INTO employees VALUES (2, 'Bob', 75000, 'Marketing');
INSERT INTO employees VALUES (3, 'Carol', 85000, 'Engineering');
UPDATE employees
SET salary = salary * 1.05
WHERE department = 'Engineering';
SELECT name, salary FROM employees WHERE department = 'Engineering';
-- Alice|94500.0
-- Carol|89250.0
Update using a join with FROM
CREATE TABLE departments (name TEXT PRIMARY KEY, budget REAL);
INSERT INTO departments VALUES ('Engineering', 500000);
INSERT INTO departments VALUES ('Marketing', 200000);
CREATE TABLE employees2 (id INTEGER PRIMARY KEY, name TEXT, bonus REAL, dept TEXT);
INSERT INTO employees2 VALUES (1, 'Alice', 0, 'Engineering');
INSERT INTO employees2 VALUES (2, 'Bob', 0, 'Marketing');
UPDATE employees2
SET bonus = departments.budget * 0.01
FROM departments
WHERE employees2.dept = departments.name;
SELECT name, bonus FROM employees2;
-- Alice|5000.0
-- Bob|2000.0
Update with RETURNING
CREATE TABLE counters (name TEXT PRIMARY KEY, value INTEGER);
INSERT INTO counters VALUES ('page_views', 41);
UPDATE counters
SET value = value + 1
WHERE name = 'page_views'
RETURNING name, value;
-- page_views|42
See Also
- INSERT for adding new rows
- DELETE for removing rows
- INSERT ... ON CONFLICT for conditional insert-or-update operations
- SELECT for querying data
더 알아보기 (Learn more)
- INSERT - 새 행 추가하기
- DELETE - 행 삭제하기
- INSERT ... ON CONFLICT (UPSERT) - 조건부 삽입/갱신
- SELECT - 데이터 조회하기