(SQLite3) INSERT문 – 테이블에 값 삽입하기

INSERT 문은 테이블에 새로운 값을 추가할 때 사용하는 명령이다. 패턴에 따라서 몇 가지 형식으로 사용된다.

  1. INSERT INTO table DEFAULT VALUES; : 테이블의 각 칼럼에 적절한 디폴트 값이 있다면 디폴트 값을 적용해서 새 Row를 추가한다. 디폴트 값에는 명시적으로 DEFAULT를 써서 선언한 값이나 자동으로 증가하는 인덱스 번호값 혹은 NULL이 사용될 수 있다.
  2. INSERT INTO table VALUES (val1, val2, val3, ... ); : 테이블의 모든 칼럼에 대해서 값을 던져주고 해당 값으로 새 레코드를 등록한다. 이 때 VALUES 뒤에 나오는 괄호의 값들은 테이블의 전체 칼럼 수와 같은 개수여야 하며, 테이블 스키마에 정의된 칼럼의 순서와 각각 매치되어야 한다.
  3. INSERT INTO table (col1, col3, col7) VALEUS (val1, val2, val3); : 1, 2의 혼합으로 칼럼의 일부에 대해서만 값을 제공하여 레코드를 생성한다. 여기에 명시되지 않은 칼럼들은 디폴트값으로 생성되기 때문에 NOT NULL이거나 디폴트가 정의되지 않았다면 에러가 난다.

여러 데이터를 한 번에 삽입하기

VALUES 뒤에 오는 ( ... ) 영역은 콤마로 구분하여 여러 개를 지정할 수 있다. 이를 통해서 INSERT 문 하나에서 여러 개의 레코드를 추가하는 것이 가능하다.

INSERT INTO table (col1, col3, col7) VALUES
  (val11, val12, val13), 
  (val21, val22, val23),
  (val31, val32, val33)
;

서브 쿼리를 사용하여 데이터 삽입하기

여러 행을 등록하는 INSERT 문에서 보면, 여러 행들이 차곡차곡 쌓여있는 그리드 형태의 데이터를 전달하여 여러 행의 데이터가 등록되는 것을 볼 수 있다. 다만 이를 일일이 타이핑해야하는 번거로움이 있다. 만약 특정 테이블에 삽입할 데이터가 다른 테이블에 있는 상황이라면 보다 빠르고 쉽게 데이터를 복사할 수 있다. VALUES .... 이하의 절은 SELECT 문으로 대체가 가능하다.

-- 2019년 10월 1일 이후 가입자의 정보를 table1에 삽입한다.
INSERT INTO table1 (name, phone, email)
  SELECT full_name, phone_number, email_address FROM customer_info
    WHERE register_dt >= "2019-10-01 00:00:00";

액션

INSERT 키워드는 REPLACE, INSERT OR REPLACE 등으로 변경될 수 있다. 이는 특정 제한에 의한 충돌 발생 시 이를 해결하기 위한 방편을 정의한다. REPLACE는 사실상 INSERT OR REPLACE와 같은 명령이며 정확하게는 INSERT 문 내에서 ON CONFILCT에 대한 처리가 추가된다. UNIQUE 제약이나 PRIMARY KEY가 겹치는 등의 삽입 오류가 발생했을 때, 새 데이터를 추가하지 않고 겹치는 데이터를 대체하는 식으로 동작한다.

임포트

csv 파일이 있다면 .import 명령을 사용해서 테이블로 바로 반입하게 된다. csv파일의 첫 행에 각 칼럼의 이름이 담겨 있다면 sqlite3는 자동으로 첫 행을 해당 칼럼의 이름으로하여 테이블을 생성하고 나머지 행들을 분해해서 테이블로 밀어넣는다. 데이터에 대한 별도의 키나 칼럼 옵션 설정이 필요 없다면 스크립트 파일에서 연동해서 읽어서 밀어넣는 방식이 아니라, csv 파일로부터 가장 쉽고 빠르게 테이블을 만들 수 있는 방법이다.

참고로, .import 명령은 sqlite3 셸에서 실행하는 명령이며, 표준 쿼리가 아니다.

sqlite> .mode csv
sqlite> .import mytbl.csv table1
sqlite> .schema table1
CREATE TABLE temp( 
  "id" TEXT,       
  "title" TEXT,    
  "body" TEXT,     
  "dt" TEXT        
);                 

명령은 .import {파일이름} {테이블이름}의 형식으로 실행한다. 실행될 때 생성되는 테이블은 모든 칼럼이 TEXT로 생성된다. 이 때 중요한 것은 .mode csv를 사용해서 입출력모드를 csv 포맷으로 맞춰주어야 한다는 점이다.

모드를 맞추지 않으면 "id,title,body,dt" TEXT 라는 단일 칼럼 테이블이 생성되고 컴마에 따른 분리도 되지 않는다.

이와 반대로 테이블을 CSV 파일로 내보내는 방법도 있는데, 별도의 포스팅에서 소개하도록 하겠다.