공공부하자개발 · 영어 학습 노트
SQL
SQL 중급서브쿼리·조인·함수·DDL·인덱스0/11 완료
  • 01서브쿼리: 스칼라·인라인 뷰·상관 서브쿼리, DB별 차이
  • 02EXISTS·IN·NOT IN 과 NULL 함정
  • 03조인 심화: INNER·OUTER·SELF·CROSS, Oracle (+)
  • 04집합 연산: UNION·UNION ALL·INTERSECT·MINUS/EXCEPT
  • 05조건 로직: CASE·DECODE·IIF
  • 06NULL 처리 함수
  • 07문자·날짜 함수 DB별 비교
  • 08DDL 과 제약 조건
  • 09인덱스 기초
  • 10집계와 GROUP BY·HAVING
  • 11뷰·시퀀스·자동 증가
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › SQL 중급 › 11 / 11

뷰·시퀀스·자동 증가

VIEW, SEQUENCE, IDENTITY, AUTO_INCREMENT
섹션 6진행 0 / 11
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6정리‹ 이전다음 ›

4. 응용 변형 예제

소스: sql-src/mid_11_view_sequence/02_sequence_identity.sql·03_dialects.sql. 시퀀스·IDENTITY 채번과 DB 별 문법 차이를 확인합니다.

변형 1: SEQUENCE 로 채번하기

sql
CREATE SEQUENCE seq_order START WITH 1000 INCREMENT BY 1 CACHE 20;

SELECT NEXT VALUE FOR seq_order AS next_id;

INSERT INTO orders_seq VALUES (NEXT VALUE FOR seq_order, '김민준', 300);
INSERT INTO orders_seq VALUES (NEXT VALUE FOR seq_order, '박서준', 500);

SELECT
       id
     , cust
     , amt
  FROM orders_seq
 ORDER BY id;

-- 같은 세션에서 마지막으로 뽑은 값을 다시 확인한다(Oracle 의 CURRVAL 과 같은 역할)
SELECT CURRENT VALUE FOR seq_order AS current_id;
text
ID   | CUST   | AMT
-----+--------+----
1001 | 김민준 | 300
1002 | 박서준 | 500
(2행)

CURRENT_ID
----------
1002
(1행)

NEXT VALUE FOR 는 호출할 때마다 다음 번호를 뽑아 소모합니다. 맨 처음 SELECT 로 1000 을 뽑아 두 INSERT 는 1001·1002 를 받았고, CURRENT VALUE FOR 로 마지막 값을 다시 확인했습니다.

변형 2: IDENTITY 컬럼 ALWAYS 와 BY DEFAULT

sql
CREATE TABLE members (id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, nm VARCHAR(20));
INSERT INTO members (nm) VALUES ('김철수'), ('이영희');

SELECT
       id
     , nm
  FROM members
 ORDER BY id;

-- GENERATED ALWAYS 는 id 값을 직접 지정할 수 없다
-- @error
INSERT INTO members (id, nm) VALUES (100, '직접지정');

-- GENERATED BY DEFAULT 는 값을 생략하면 자동 채번하되 직접 지정도 허용한다
CREATE TABLE members2 (id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, nm VARCHAR(20));
INSERT INTO members2 (nm) VALUES ('김철수');
INSERT INTO members2 (id, nm) VALUES (100, '직접지정');

-- 카운터가 직접 지정한 100 을 기준으로 당겨지지 않아 다음 값은 여전히 2다
INSERT INTO members2 (nm) VALUES ('다음값');

SELECT
       id
     , nm
  FROM members2
 ORDER BY id;
text
ID | NM
---+-------
1  | 김철수
2  | 이영희
(2행)

예상 오류: Generated column "PUBLIC.MEMBERS.ID" cannot be assigned

ID  | NM
----+---------
1   | 김철수
2   | 다음값
100 | 직접지정
(3행)

GENERATED ALWAYS 는 id 값을 직접 지정하면 오류가 나지만, GENERATED BY DEFAULT 는 id = 100 을 직접 넣어도 받아줍니다. 다만 자동 채번 카운터는 그 값을 기준으로 다시 맞춰지지 않아 다음 값이 여전히 2 이므로, 앞으로 카운터가 100 근처까지 올라오면 직접 지정한 값과 충돌할 위험이 있습니다.

변형 3: 롤백으로 생기는 구멍(gap)

sql
SELECT NEXT VALUE FOR seq_order AS before_rollback;

SET AUTOCOMMIT FALSE;
INSERT INTO orders_seq VALUES (NEXT VALUE FOR seq_order, '취소될주문', 100);
ROLLBACK;

-- 롤백된 행은 없지만 방금 뽑은 번호는 이미 소모되어 되돌아오지 않는다
INSERT INTO orders_seq VALUES (NEXT VALUE FOR seq_order, '최도윤', 200);
COMMIT;
SET AUTOCOMMIT TRUE;

SELECT
       id
     , cust
     , amt
  FROM orders_seq
 ORDER BY id;
text
BEFORE_ROLLBACK
---------------
1003
(1행)

ID   | CUST   | AMT
-----+--------+----
1001 | 김민준 | 300
1002 | 박서준 | 500
1005 | 최도윤 | 200
(3행)

1003(맨 위 조회)과 1004(롤백된 INSERT 에서 소모)는 어느 행에도 남지 않아, 결과는 1002 다음이 곧바로 1005 입니다. 2.7절에서 설명한 구멍이 그대로 재현됩니다.

변형 4: DB 별 채번 문법 비교

DB 시퀀스·자동 증가 세션에서 마지막 값 확인
Oracle·Tibero CREATE SEQUENCE, seq.NEXTVAL seq.CURRVAL(NEXTVAL 을 먼저 호출해야 함)
MySQL AUTO_INCREMENT(테이블당 1개, 키 컬럼) LAST_INSERT_ID()(세션·연결별)
MSSQL IDENTITY(시작,증가), 2012 부터 SEQUENCE SCOPE_IDENTITY()(현재 범위)
sql
-- Oracle · Tibero
SET MODE Oracle;
CREATE SEQUENCE seq_ora START WITH 500 INCREMENT BY 1;

SELECT seq_ora.NEXTVAL AS next_id FROM DUAL;

-- CURRVAL 은 같은 세션에서 NEXTVAL 을 한 번 호출한 뒤에만 쓸 수 있다
SELECT seq_ora.CURRVAL AS curr_id FROM DUAL;

-- MySQL
SET MODE MySQL;
CREATE TABLE members_my (id INT AUTO_INCREMENT PRIMARY KEY, nm VARCHAR(20));
INSERT INTO members_my (nm) VALUES ('김철수'), ('이영희');

-- 이 커넥션이 마지막으로 만든 자동 증가 값(세션별로 따로 관리)
SELECT LAST_INSERT_ID() AS last_id;
text
NEXT_ID
-------
500
(1행)

CURR_ID
-------
500
(1행)

LAST_ID
-------
2
(1행)

Oracle 은 12c 부터 시퀀스 없이도 표준 IDENTITY 컬럼(2.6절)을 바로 쓸 수 있습니다. MySQL 은 SEQUENCE 객체가 따로 없고, MariaDB 는 10.3 부터 지원해 MySQL 과 다릅니다. InnoDB 는 8.0 부터 AUTO_INCREMENT 카운터가 재시작 후에도 유지되며, 그 전 버전은 재시작 때 MAX(id) + 1 로 다시 계산했습니다.

sql
-- MSSQL
SET MODE MSSQLServer;
CREATE TABLE members_ms (id INT IDENTITY(1,1) PRIMARY KEY, nm NVARCHAR(20));
INSERT INTO members_ms (nm) VALUES (N'김철수');
INSERT INTO members_ms (nm) VALUES (N'이영희');

-- 현재 범위(스코프)에서 마지막으로 만든 IDENTITY 값
SELECT SCOPE_IDENTITY() AS scope_id;

-- 2012 부터: SEQUENCE 객체도 함께 쓸 수 있다
CREATE SEQUENCE seq_ms START WITH 1 INCREMENT BY 1;

SELECT NEXT VALUE FOR seq_ms AS next_id;
text
SCOPE_ID
--------
2
(1행)

NEXT_ID
-------
1
(1행)
주의

MSSQL 은 SCOPE_IDENTITY() 말고 @@IDENTITY 도 있는데, 트리거가 만든 값까지 포함해 현재 세션의 마지막 IDENTITY 값을 돌려줍니다. 트리거가 다른 테이블에 행을 추가하면 엉뚱한 값이 나올 수 있어 보통 SCOPE_IDENTITY() 를 씁니다. IDENTITY 컬럼에 값을 직접 넣으려면 SET IDENTITY_INSERT 테이블 ON 을 먼저 실행해야 합니다. @@IDENTITY·SET IDENTITY_INSERT 모두 H2 가 지원하지 않아 문법 검토만입니다.

응용 변형 예제
  • 변형 1: SEQUENCE 로 채번하기
  • 변형 2: IDENTITY 컬럼 ALWAYS 와 BY DEFAULT
  • 변형 3: 롤백으로 생기는 구멍(gap)
  • 변형 4: DB 별 채번 문법 비교
이전 섹션3 코드 예제4 / 6다음 섹션5 자주 하는 실수 (Tip)