DBAtlas · 데이터베이스 운영 아틀라스

변경된 행 반환(RETURNING / OUTPUT)

Oracle

-- Single row: RETURNING ... INTO (PL/SQL bind variable)
UPDATE employee SET salary = salary * 1.1
WHERE id = 5
RETURNING salary INTO :new_salary;

-- Get back the key generated by an INSERT
INSERT INTO employee (name) VALUES ('Ayse')
RETURNING id INTO :new_id;

RETURNING은 별도의 SELECT 없이 INSERT/UPDATE/DELETE로 변경된 행의 값(예: 자동 생성 ID)을 반환한다. Oracle에서는 단일 행은 RETURNING ... INTO로 바인드 변수에, 여러 행은 RETURNING ... BULK COLLECT INTO로 컬렉션에 반환한다.

PostgreSQL

INSERT INTO employee (name, salary)
VALUES ('Ayse', 15000)
RETURNING id, name;

UPDATE employee SET salary = salary * 1.1
WHERE department = 'IT'
RETURNING id, salary;

PostgreSQL의 RETURNING 절은 매우 유연하다. INSERT, UPDATE, DELETE, MERGE 문의 영향을 받은 행의 모든 컬럼(계산식 포함)을 결과 집합으로 바로 반환한다. 생성된 serial/identity 값을 얻는 가장 깔끔한 방법이다.

MySQL

-- MySQL has no RETURNING; the generated key is retrieved separately:
INSERT INTO employee (name, salary) VALUES ('Ayse', 15000);
SELECT LAST_INSERT_ID();

-- MariaDB 10.5+ supports INSERT ... RETURNING:
INSERT INTO employee (name) VALUES ('Ayse') RETURNING id;

MySQL은 표준 RETURNING을 지원하지 않는다. INSERT로 생성된 auto-increment 키는 LAST_INSERT_ID()로 가져오고, 갱신된 값은 별도의 SELECT로 읽는다. MariaDB는 10.5부터 INSERT ... RETURNING을, 10.0부터 DELETE ... RETURNING을 제공한다.

SQL Server

INSERT INTO employee (name, salary)
OUTPUT INSERTED.id, INSERTED.name
VALUES ('Ayse', 15000);

UPDATE employee SET salary = salary * 1.1
OUTPUT DELETED.salary AS old_salary, INSERTED.salary AS new_salary
WHERE id = 5;

SQL Server에서 이에 해당하는 것은 OUTPUT 절이다. INSERTED(새 값)와 DELETED(이전 값) 의사 테이블에 접근하며, UPDATE에서는 둘 다 사용할 수 있다. OUTPUT ... INTO로 결과를 테이블/테이블 변수에 쓸 수 있다. 변경 내용을 감사 테이블에 복사하는 데 적합하다.

MongoDB

// findOneAndUpdate returns the modified document
db.employee.findOneAndUpdate(
  { id: 5 },
  { $mul: { salary: 1.1 } },
  { returnDocument: "after" }   // return the updated version
)

MongoDB에서 findOneAndUpdate / findOneAndDelete / findOneAndReplace 명령은 영향을 받은 문서를 단일 원자적 작업으로 반환한다. returnDocument: 'before'는 변경 전 버전을, 'after'는 변경 후 버전을 반환한다. insertOne은 삽입된 문서의 _id를 반환한다.

Redis

# Some commands return the old/new value directly:
SET counter 0 GET       # (6.2+) returns the old value and writes the new one (replaces GETSET)
INCR visits          # increments and returns the new value

Redis에는 별도의 RETURNING이 없지만 많은 쓰기 명령이 결과를 바로 반환한다. INCR/INCRBY는 새 값을, SET ... GET은 이전 값을(GETSET은 6.2부터 deprecated), LPOP/RPOP은 제거된 요소를 반환한다. 원자적 읽기-쓰기에서 이 동작이 RETURNING을 대신한다.

Elasticsearch

# The _update response can return the result:
POST employee/_update/5
{
  "script": { "source": "ctx._source.salary *= 1.1" },
  "_source": true
}
# The response returns the updated document in get._source

Elasticsearch에서 index/update 작업은 결과 메타데이터(_id, _version, result)를 반환한다. 갱신된 문서 본문을 얻으려면 _update 요청에 '_source': true를 추가한다. 응답의 get 필드에 현재 _source가 포함되므로 별도의 GET 호출이 필요 없다.

DBAtlas에서 열기 →