INSERT
INSERT
이 페이지는 SQLite의 INSERT 문에 대해 설명합니다. INSERT는 세 가지 기본 형태로 제공되며, 테이블에 새 행을 추가하는 데 사용됩니다. 각 형태는 삽입할 데이터의 출처와 방식이 다릅니다.
출처: 문서
본문
1. 개요
insert-stmt:
WITH RECURSIVE common-table-expression , REPLACE INSERT OR ROLLBACK INTO ABORT FAIL IGNORE REPLACE schema-name . table-name AS alias ( column-name ) , VALUES ( expr ) , , upsert-clause select-stmt upsert-clause DEFAULT VALUES returning-clause
common-table-expression:
table-name ( column-name ) AS NOT MATERIALIZED ( select-stmt ) ,
expr:
literal-value bind-parameter schema-name . table-name . column-name unary-operator expr expr binary-operator expr function-name ( function-arguments ) filter-clause over-clause ( expr ) , CAST ( expr AS type-name ) expr COLLATE collation-name expr NOT LIKE GLOB REGEXP MATCH expr expr ESCAPE expr expr ISNULL NOTNULL NOT NULL expr IS NOT DISTINCT FROM expr expr NOT BETWEEN expr AND expr expr NOT IN ( select-stmt ) expr , schema-name . table-function ( expr ) table-name , NOT EXISTS ( select-stmt ) CASE expr WHEN expr THEN expr ELSE expr END raise-function
filter-clause:
FILTER ( WHERE expr )
function-arguments:
DISTINCT expr , * ORDER BY ordering-term ,
ordering-term:
expr COLLATE collation-name DESC ASC NULLS FIRST NULLS LAST
literal-value:
CURRENT_TIMESTAMP numeric-literal string-literal blob-literal NULL TRUE FALSE CURRENT_TIME CURRENT_DATE
over-clause:
OVER window-name ( base-window-name PARTITION BY expr , ORDER BY ordering-term , frame-spec )
frame-spec:
GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING RANGE ROWS UNBOUNDED PRECEDING expr PRECEDING CURRENT ROW expr PRECEDING CURRENT ROW expr FOLLOWING expr PRECEDING CURRENT ROW expr FOLLOWING EXCLUDE CURRENT ROW EXCLUDE GROUP EXCLUDE TIES EXCLUDE NO OTHERS
ordering-term:
expr COLLATE collation-name DESC ASC NULLS FIRST NULLS LAST
raise-function:
RAISE ( ROLLBACK , expr ) IGNORE ABORT FAIL
type-name:
name ( signed-number , signed-number ) ( signed-number )
signed-number:
+ numeric-literal -
returning-clause:
RETURNING expr AS column-alias * ,
select-stmt:
WITH RECURSIVE common-table-expression , SELECT DISTINCT result-column , ALL FROM table-or-subquery join-clause , WHERE expr GROUP BY expr HAVING expr , WINDOW window-name AS window-defn , VALUES ( expr ) , , compound-operator select-core ORDER BY LIMIT expr ordering-term , OFFSET expr , expr
compound-operator:
UNION UNION INTERSECT EXCEPT ALL
join-clause:
table-or-subquery join-operator table-or-subquery join-constraint
join-constraint:
USING ( column-name ) , ON expr
join-operator:
NATURAL LEFT OUTER JOIN , RIGHT FULL INNER CROSS
ordering-term:
expr COLLATE collation-name DESC ASC NULLS FIRST NULLS LAST
result-column:
expr AS column-alias * table-name . *
table-or-subquery:
schema-name . table-name AS table-alias INDEXED BY index-name NOT INDEXED table-function-name ( expr ) , AS table-alias ( select-stmt ) ( table-or-subquery ) , join-clause
window-defn:
( base-window-name PARTITION BY expr , ORDER BY ordering-term , frame-spec )
frame-spec:
GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING RANGE ROWS UNBOUNDED PRECEDING expr PRECEDING CURRENT ROW expr PRECEDING CURRENT ROW expr FOLLOWING expr PRECEDING CURRENT ROW expr FOLLOWING EXCLUDE CURRENT ROW EXCLUDE GROUP EXCLUDE TIES EXCLUDE NO OTHERS
upsert-clause:
ON CONFLICT ( indexed-column ) WHERE expr DO , conflict target UPDATE SET column-name-list = expr WHERE expr NOTHING , column-name
column-name-list:
( column-name ) ,
indexed-column:
column-name COLLATE collation-name DESC expr ASC
INSERT 문에는 세 가지 기본 형식이 있어요.
- INSERT INTO table VALUES(...);
첫 번째 형식("VALUES" 키워드를 쓰는 형식)은 기존 테이블에 새 행을 하나 이상 만들어요. table-name 뒤의 column-name 목록을 생략하면 각 행에 넣는 값의 개수가 테이블의 열 개수와 같아야 해요. 이 경우 VALUES 목록에 있는 각 항목의 맨 왼쪽 식을 계산한 결과가 새 행의 맨 왼쪽 열에 들어가고, 그 뒤의 식들도 같은 방식으로 차례로 들어가요. column-name 목록을 지정하면 VALUES 목록의 각 항목에 있는 값의 개수가 지정된 열 개수와 일치해야 해요. 새 행에서 이름이 지정된 각 열은 해당 VALUES 식을 계산한 결과로 채워져요. 열 목록에 없는 테이블 열은 기본 열 값(CREATE TABLE 문의 일부로 지정된 값)으로 채워지고, 기본값이 지정되지 않았다면 NULL로 채워져요.
- INSERT INTO table SELECT ...;
INSERT 문의 두 번째 형식은 VALUES 절 대신 SELECT 문을 써요. SELECT 문을 실행해서 돌아온 각 데이터 행마다 테이블에 새 항목이 하나씩 삽입돼요. column-list를 지정했다면 SELECT 결과의 열 개수가 column-list 항목 개수와 같아야 해요. column-list를 지정하지 않았다면 SELECT 결과의 열 개수가 테이블의 열 개수와 같아야 해요. 복합 SELECT 문과 ORDER BY 및/또는 LIMIT 절이 있는 SELECT 문을 포함한 모든 SELECT 문은 이 형식의 INSERT 문에 사용할 수 있어요.
파싱 모호성을 피하려면 upsert 절이 있을 때 SELECT 문에 항상 WHERE 절을 넣어야 해요. 그 WHERE 절이 단순히 "WHERE true"라도요. WHERE 절이 없으면 파서는 "ON" 토큰이 SELECT 문의 조인 제약 조건의 일부인지, 아니면 upsert 절의 시작인지 알 수 없어요.
- INSERT INTO table DEFAULT VALUES;
INSERT 문의 세 번째 형식은 DEFAULT VALUES를 사용하는 거예요. INSERT ... DEFAULT VALUES 문은 지정된 테이블에 새 행 하나를 삽입해요. 새 행의 각 열은 기본값으로 채워지고, CREATE TABLE 문의 열 정의에 기본값이 지정되지 않았다면 NULL로 채워져요. DEFAULT VALUES 뒤에는 upsert 절을 사용할 수 없어요.
처음의 "INSERT" 키워드는 "REPLACE"나 "INSERT OR *action*"으로 바꿔서 그 INSERT 명령 하나에서 사용할 대체 제약 조건 충돌 해결 알고리즘을 지정할 수 있어요. MySQL과의 호환성을 위해 파서는 단일 키워드 REPLACE를 "INSERT OR REPLACE"의 별칭으로 허용해요.
table-name 앞의 선택적 *schema-name***.** 접두사는 최상위 INSERT 문에서만 지원돼요. CREATE TRIGGER 문 안에 있는 INSERT 문에서는 테이블 이름이 한정되지 않은 상태여야 해요. 마찬가지로 "DEFAULT VALUES" 형식의 INSERT 문도 최상위 INSERT 문에서만 지원되고 트리거 안의 INSERT 문에서는 지원되지 않아요.
선택적 "AS alias" 구문은 내용이 삽입되는 테이블의 다른 이름을 제공해요. 그 별칭 이름은 UPSERT의 WHERE 절과 SET 절에서 사용할 수 있어요. upsert 절이 없다면 별칭은 쓸모없지만 해롭지도 않아요.
INSERT가 고유성 제약 조건을 위반하게 되는 경우 INSERT가 UPDATE처럼 동작하도록 만드는 추가 후행 구문은 별도의 UPSERT 문서를 참조하세요. upsert 절은 "INSERT ... DEFAULT VALUES"에서는 허용되지 않아요.
이 페이지는 2026-05-14 15:13:28Z에 마지막으로 업데이트되었어요.