6.1 Inesrt (SQL)
DML
DDL (Data Definition Language)가 테이블에 저장할 데이터를 정의하는 구문이라고 하면, DML (Data Manipulaion Language)은 DDL을 통해서 정의된 테이블에 레코드 데이터를 생성, 변경, 삭제하는 구문이다.
즉, DML은 Database에 데이터를 수정하는 구문으로, INSERT
, UPDATE
, DELETE
가 포함된다.
레코드 생성 구문
INSERT
는 테이블에 새로운 레코드를 생성할 떄 사용하는 SQL 구문이다. 문법은 다음과 같다:
1
2
3
4
5
6
7
8
-- tb_name: 테이블명
-- col_name: 컬럼명
-- val: 입력값
INSERT INTO tb_name (col_name1, col_name2, ...)
VALUES
(val1_1, val2_1, ...),
(val1_2, val2_2, ...),
...;
여기서 컬럼명을 의미하는 col_name과 입력값을 의미하는 val는 순서가 맞아야한다. 또한 여러개의 val 조합을 입력함으로써 한번에 여러개의 레코드를 생성할 수 있다.
INSERT에 사용되는 col_name은 DDL 구문을 통해서 이미 정의되어 있어야한다. 또한 val 값은 정의시 지정한 타입과 일치해야한다.
레코드 생성의 활용
Table 0: Employee Table
employee_id | name | created_at | |
---|---|---|---|
1 | 김철수 | 2023-01-01 00:00:00 | ironsoo@naver.com |
2 | 이영희 | 2023-01-02 15:20:00 | 202@gmail.com |
3 | 홍길동 | 2023-01-03 09:55:00 | hkd@gmail.com |
5.2 Create Table 에서 생성한 Employee 테이블을 이용한 예시를 들어보자. 새로운 직원이 입사했고, 이에따라 새로운 직은을 등록해야한다. 다음의 직원 정보를 이용하여 쿼리문을 작성해보면:
- employee_id: 마지막 레코드 + 1
- name: 홍길순
- created_at: 생성 시각
- email: hks@gmail.com
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 레코드의 생성
INSERT INTO employee (employee_id, created_at, name, email)
VALUES (4, NOW(), '홍길순', 'hks@gmail.com');
-- 생성된 레코드 조회
SELECT * FROM employee;
-- 조회 결과:
-- +-------------+------+---------------------+-------------------+
-- | employee_id | name | created_at | email |
-- +-------------+------+---------------------+-------------------+
-- | 1 | 김철수 | 2023-01-01 00:00:00 | ironsoo@naver.com |
-- | 2 | 이영희 | 2023-01-02 15:20:00 | 202@gmail.com |
-- | 3 | 홍길동 | 2023-01-03 09:55:00 | hkd@gmail.com |
-- | 4 | 홍길순 | 2023-01-04 13:20:00 | hks@gmail.com |
-- +-------------+------+---------------------+-------------------+
INSERT를 실해할 때 컬럼의 타입이 SERIAL 타입이거나 기본값이 정의되어 있는 경우에는 생략하더라도 자동으로 생성한다. 또한 nullable한 컬럼은 값을 추가할때 생략시 NULL로 저장된다.
Employee 테이블에선 기본값으로 설정한 employee_id와 created_at은 생략 가능하며, 결과는 같다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 레코드의 생성
INSERT INTO employee (name, email)
VALUES ('홍길순', 'hks@gmail.com');
-- 생성된 레코드 조회
SELECT * FROM employee;
-- 조회 결과:
-- +-------------+------+---------------------+-------------------+
-- | employee_id | name | created_at | email |
-- +-------------+------+---------------------+-------------------+
-- | 1 | 김철수 | 2023-01-01 00:00:00 | ironsoo@naver.com |
-- | 2 | 이영희 | 2023-01-02 15:20:00 | 202@gmail.com |
-- | 3 | 홍길동 | 2023-01-03 09:55:00 | hkd@gmail.com |
-- | 4 | 홍길순 | 2023-01-04 13:20:00 | hks@gmail.com |
-- +-------------+------+---------------------+-------------------+
INSERT … FROM 구문
만약 다른테이블의 값이 필요한 경우 일일이 VALUES를 작성하지 않더라도, FROM을 이용함으로써 한번 많은 레코드를 생성할 수 있다. INSERT ... FROM
의 문법은 다음과 같다:
- tb1: 값을 입력할 테이블
- tb2: 데이터를 가져올 테이블
1
2
3
INSERT INTO tb1 (col1, col2, ...)
VALUES (tb2.col1, tb2.col2, ...) FROM tb2
WHERE ...;
테이블을 추가할 때는 초기값을 입력하기도 한다. 특히 기존 데이터와의 연결관계를 가진 테이블을 추가하는 경우에는 연결관계에 맞는 초기값을 입력해야한다. 이런 상황에서 INSERT ... FROM
구문을 사용하여 초기값을 채울 수 있다.
Table 1: Job Table
job_id | name | created_at |
---|---|---|
1 | 개발자 | 2023-01-01 00:00:00 |
2 | 기획자 | 2023-01-02 00:-0:00 |
Table 2: EmployeeJob Table
employee_id | job_id | hired_at |
---|---|---|
Employee, Job, EmployeeJob 테이블을 이용하여 예를 들어보자. Employee 테이블에는 사원 정보들이 있고 Job 테이블에는 개발자라는 직무가 존재한다. 사원과 직무는 EmployeeJob 테이블에 job_id와 employee_id를 저장함으로써 연결할 수 있다.
Q. 위의 테이블 정보를 바탕으로 1월 2일 이후의 입사자는 개발자로 등록을 하려한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- EmployeeJob 레코드 생성
INSERT INTO employee_job (employee_id, job_id, hired_at)
VALUES (e.employee_id, 1, NOW())
FROM employee e
WHERE e.created_at >= '2023-01-02';
-- 저장된 레코드 조회
SELECT * FROM employee_job;
-- 조회 결과
-- +-------------+--------+---------------------+
-- | employee_id | job_id | hired_at |
-- +-------------+--------+---------------------+
-- | 2 | 1 | 2023-01-03 15:00:00 |
-- | 3 | 1 | 2023-01-03 15:00:00 |
-- +-------------+--------+---------------------+