안녕하세요. SQLER의 코난 김대우입니다.
이번 강좌에서는, 3-1. 데이터 삽입, 삭제, 수정 - INSERT를 이용한 행 삽입을 진행 하겠습니다.
SQLER에서 진행되는, 챗GPT와 함께 배우는 SQL Server 강좌 목록
이번 강좌는 데이터의 삽입, 수정, 삭제 중 첫 번째, 데이터 삽입니다.
TL;DR
INSERT 구문으로 데이터를 삽입합니다. VALUES로 데이터 값을 지정할 수 있으며, IDENTITY, 기본값(DEFAULT), 기본 키(PRIMARY KEY) 등 테이블 제약에 주의해 INSERT 해야 합니다.
지난 강좌에서는 데이터를 다양한 방법으로 조회하는 SELECT를 진행했습니다. 이번에는 INSERT 구문을 이용해 데이터를 삽입하는 과정을 진행합니다. 그럼 데이터를 삽입하는 INSERT에 대해 알아보겠습니다.
INSERT 구문
INSERT 구문은 이전 JOIN 강좌 예제와 UNION 강좌에서 짧게 수행했습니다.
USE AdventureWorks; GO -- 만약 테이블이 존재하면 삭제 IF OBJECT_ID(N'dbo.members_test1', N'U') IS NOT NULL DROP TABLE dbo.members_test1; GO -- INSERT 테스트 테이블 생성 CREATE TABLE members_test1 ( member_id INT PRIMARY KEY, member_name NVARCHAR(10), email NVARCHAR(15) ); GO
위와 같이 테스트 테이블을 CREATE TABLE 구문으로 생성합니다. 테이블과 테이블 생성에 대해서는 이후 강좌에서 상세하게 다룹니다.
테이블 각 컬럼은 INT로 숫자 값, NVARCHAR로 유니코드 문자열 값 등을 입력받습니다.
INSERT 구문은 아래와 같이 수행합니다.
-- 1개 로우 INSERT 구문 INSERT INTO members_test1(member_id, member_name, email) VALUES(1, N'김대우', N'kdw@example.com'); GO -- 여러 개 로우 INSERT 구문 INSERT INTO members_test1(member_id, member_name, email) VALUES (2, N'손석구', N'ssk@example.com'), (3, N'박은빈', N'peb@example.com'); GO
테이블 명 뒤에 ()와 함께 데이터를 삽입할 컬럼 순서를 나열합니다. VALUES 이후 입력할 값을 넣습니다.
SELECT * FROM members_test1; GO
테이블 정의처럼 문자열 데이터형을 INSERT 할 경우에는 작은따옴표 '를 이용해 문자열 주위를 감싸고 INSERT 합니다. 숫자형 데이터를 넣을 경우는 숫자만 쓰면 됩니다.
데이터형에 대해 궁금하면 이전 강좌 2-4 데이터형(Data type)과 함수(Function)를 참조하세요.
INSERT 구문 예제
INSERT 구문 사용 예제를 더 살펴봅니다.
-- 삽입할 컬럼의 순서를 변경해 INSERT INSERT INTO members_test1(email, member_name, member_id) VALUES(N'psj@example.com', N'박서준', 4); GO SELECT * FROM members_test1; GO
INSERT 구문에서 테이블명 뒤 컬럼 리스트 순서를 변경했습니다.
-- 컬럼 리스트 없이 VALUE만 이용해 INSERT INSERT INTO members_test1 VALUES(5, N'김태리', N'ktr@example.com'); GO SELECT * FROM members_test1; GO
테이블 뒤의 컬럼 리스트 없이 순차적으로 VALUE를 나열해 입력 가능합니다.
특정 컬럼에만 값을 넣고 싶을 때는 이렇게 가능합니다.
-- email 컬럼 값 없이 INSERT 수행(부분 데이터 삽입) INSERT INTO members_test1(member_id, member_name) VALUES(6, N'이정재'); GO SELECT * FROM members_test1; GO
조회해보면 6번 이정재 로우는 email 주소가 NULL로 표시됩니다.
그럼 INSERT 구문 정보 확인하겠습니다.
INSERT 구문 정보
INSERT [INTO] {table_name | view_name}[(column_list)] {VALUES | values_list | select_statement} |
INSERT 절
행을 삽입할 테이블 또는 뷰를 지정. 전체 행이 아닌 특정 컬럼을 지정하는 컬럼 리스트를 사용할 수 있음.
VALUES절
삽입할 데이터를 지정. 자료형에 따라 각각의 입력 형식을 적용
디폴트 값 옵션
DEFAULT VALUES
INSERT table_name DEFAULT VALUES
모든 컬럼에 대해 디폴트 값을 가지는 행을 삽입한다.
DEFAULT 값 입력
INSERT table_name VALUES( ..., DEFAULT, .....)
지정된 컬럼에 디폴트 값을 삽입한다.
- 컬럼이 IDENTITY 속성이거나, timestamp 자료형인 경우 해당하는 값이 삽입된다.
- DEFAULT는 IDENTITY 속성을 가지는 컬럼에 대해 유효하지 않다.
- 컬럼에 디폴트가 없고 NULL이 허용되는 경우에는 NULL 이 삽입된다.
- 컬럼에 디폴트가 없고 NULL이 허용되지 않는 경우에는 에러를 반환하고 INSERT는 실패한다.
부분 데이터 삽입
NULL이나 디폴트 값을 허용하는 컬럼에 대해서는 데이터를 지정하지 않을 수 있다.
INSERT [INTO] [table_name | view_name} (column_list) {VALUES | vlaues_list | select_statement} |
- INSERT 절에 컬럼명을 명시한다.
- VALUES 절의 값들은 각각 column_list의 컬럼에 대응된다.
- 나열되지 않은 컬럼에 대해서는 DEFAULT와 같이 처리된다.
INSERT SELECT SQL 구문
지난 SELECT INTO 강좌에서 짧게 소개해 드렸습니다. 테이블로부터 SELECT 쿼리를 수행한 다음, 결과셋을 테이블에 추가할 수 있습니다.
1번 테이블에서 email 주소가 NULL이 아닌 데이터만 다른 테이블로 복사하려고 합니다.
-- 테이블1 쿼리 수행 SELECT member_id, member_name, email FROM members_test1 WHERE email IS NOT NULL; GO
위 쿼리를 수행해 테스트 테이블 1에서 NULL이 아닌 로우를 확인합니다.
-- 만약 테이블이 존재하면 삭제 IF OBJECT_ID(N'dbo.members_test2', N'U') IS NOT NULL DROP TABLE dbo.members_test2; GO -- INSERT SELECT 테스트 테이블 생성 CREATE TABLE members_test2 ( member_id INT PRIMARY KEY, member_name NVARCHAR(10), email NVARCHAR(15) ); GO -- INSERT SELECT 수행 INSERT INTO members_test2(member_id, member_name, email) SELECT member_id, member_name, email FROM members_test1 WHERE email IS NOT NULL; GO -- 데이터 조회 SELECT * FROM members_test2; GO
이렇게 INSERT SELECT 구문을 수행해 결과셋을 다른 테이블로 복사할 수 있습니다.
INSERT SELECT 구문 정보
SELECT 구문을 사용하여 하나 이상의 다른 테이블로부터 이미 존재하는 테이블로 로우를 삽입할 수 있다.
INSERT table_name SELECT column_list FROM table_list WHERE search_conditions |
고려사항
- 같은 테이블에서도 INSERT SELECT 가능.
- 삽입할 테이블과 SELECT 결과 집합은 컬럼의 수, 컬럼의 순서, 자료형 등에 호환성이 있어야 함.
- 매칭되는 컬럼은 같은 자료형이거나 SQL 서버가 자동 호환되도록 변환 할 수 있는 자료형이어야 함.
- INSERT만 사용하는 경우와 다르게, 한 번에 여러 행을 삽입.
- 생략된 컬럼에 대해서는 해당 컬럼에 디폴트가 존재하는지 또는 NULL이 허용되는지를 확인해야 함.
IDENTITY와 DEFAULT, PRIMARY KEY
처음 SQL을 공부하는 SQLER가 어려워하는 부분이 이런 IDENTITY, DEFAULT, PRIMARY KEY 같은 테이블 제약(Constraints)으로 인해 INSERT가 실패하는 경우입니다. 처음 SQL을 공부하고 INSERT 할 때 이런 오류를 접하면 난감하지요. 간략히 위의 항목들을 리뷰합니다.
IDENTITY
IDENTITY는 자동 증가 값을 컬럼에 추가합니다. (1, 1)은 1부터 시작해 값이 자동으로 1씩 증가하는 seed와 step 값입니다. 이 IDENTITY컬럼이 포함된 테이블에 INSERT를 수행하는 예제입니다.
-- 만약 테이블이 존재하면 삭제 IF OBJECT_ID(N'dbo.members_test3', N'U') IS NOT NULL DROP TABLE dbo.members_test3; GO -- IDENTITY, DEFAULT 컬럼 테스트 테이블 CREATE TABLE members_test3 ( member_num INT PRIMARY KEY IDENTITY(1, 1), member_name NVARCHAR(10), email NVARCHAR(15), register_date datetime DEFAULT GETDATE() ); GO
member_num 컬럼에 IDENTITY 제약 속성이 설정, register_date에 DEFAULT 제약으로 현재날짜와 시간을 가져오는 GETDATE() 값을 추가하고 테이블을 생합니다.
-- 1개 로우 INSERT 구문 --에러 INSERT INTO members_test3(member_num, member_name, email, register_date) VALUES(1, N'김대우', N'kdw@example.com', '2023-07-09'); GO 메시지 544, 수준 16, 상태 1, 줄 457 IDENTITY_INSERT가 OFF로 설정되면 테이블 'members_test3'의 ID 열에 명시적 값을 삽입할 수 없습니다.
IDENTITY가 설정된 컬럼에 데이터를 추가하려고 하면 이렇게 IDENTITY_INSERT 오류가 발생합니다. (항상 오류를 상세히 읽어두세요.)
그렇다면, IDENTITY가 걸린 컬럼에 데이터를 넣으려면 어떻게 해야 할까요?
간단합니다. IDENTITY가 걸린 컬럼을 제외하고 INSERT 하면 됩니다.
-- IDENTITY 컬럼 빼고 INSERT 수행 INSERT INTO members_test3(member_name, email, register_date) VALUES(N'김대우', N'kdw@example.com', '2023-07-09'); GO SELECT * FROM members_test3; GO 결과 member_num member_name email register_date ----------- ----------- ------------- ----------------------- 1 김대우 kdw@example.com 2023-07-09 00:00:00.000
member_num 컬럼에 값을 빼고 INSERT 했지만, IDENTITY로 값이 자동입력 되었습니다.
☑️ 챗GPT 활용: SQL SERVER IDENTITY 예제를 알려줘
DEFAULT
테이블을 생성할 때 register_date에 DEFAULT 값으로 현재 일시를 가져오는 GETDATE() 함수를 사용했습니다. 마찬가지로, DEFAULT가 설정된 컬럼에 값을 빼고 INSERT 하면, DEFAULT 값이 컬럼에 자동 추가됩니다.
-- DEFAULT 컬럼 register_date를 빼고 수행 INSERT INTO members_test3(member_name, email) VALUES(N'손석구', N'ssk@example.com'); INSERT INTO members_test3(member_name, email) VALUES(N'박은빈', N'peb@example.com'); GO SELECT * FROM members_test3; GO member_num member_name email register_date ----------- ----------- ----------- ----------------------- 1 김대우 kdw@example.com 2023-07-09 00:00:00.000 2 손석구 ssk@example.com 2023-07-09 14:08:46.130 3 박은빈 peb@example.com 2023-07-09 14:10:46.607
IDENTITY 컬럼은 자동으로 값이 1부터 1씩 증가하고, DEFAULT 값이 설정된 register_date 컬럼은 현재일시가 추가됩니다.
기본 키(PRIMARY KEY) 제약
기본 키는 설정된 컬럼에 중복 값과 NULL 값을 허용하지 않습니다.
-- 만약 테이블이 존재하면 삭제 IF OBJECT_ID(N'dbo.members_test4', N'U') IS NOT NULL DROP TABLE dbo.members_test4; GO -- PRIMARY KEY 제약 테스트 테이블 CREATE TABLE members_test4 ( member_num INT PRIMARY KEY, member_name NVARCHAR(10), email NVARCHAR(15) ); GO -- 첫 INSERT 성공 INSERT INTO members_test4(member_num, member_name, email) VALUES(1, N'김대우', N'kdw@example.com'); GO -- PRIMARY KEY 제약이 설정된 member_num에 같은 값 1을 넣으면 오류 발생 INSERT INTO members_test4(member_num, member_name, email) VALUES(1, N'손석구', N'ssk@example.com'); GO 오류 메시지 2627, 수준 14, 상태 1, 줄 522 PRIMARY KEY 제약 조건 'PK__members___F5CCF2F92FB81472'을(를) 위반했습니다. 개체 'dbo.members_test4'에 중복 키를 삽입할 수 없습니다. 중복 키 값은 (1)입니다. 문이 종료되었습니다.
갑자기 IDENTITY나 DEFAULT, 기본 키(PRIMARY KEY)가 나와 복잡해진 느낌이지만, INSERT 할 때 워낙 자주 발생하고, 처음 SQL을 공부하는 SQLER를 좌절시키는 이슈들이라 간략하게 적었습니다. 이후 테이블 제약(Constraints) 강좌에서 한번 더 다루게 됩니다.
테이블 삭제
그렇다면, 테이블을 삭제하려면 어떻게 해야 할까요? DROP 테이블 구문을 사용합니다.
이번 강좌에서 생성한 member_test 테이블들을 삭제하겠습니다.
-- 테스트에 사용한 member_test 테이블들을 삭제 DROP TABLE members_test1; DROP TABLE members_test2; DROP TABLE members_test3; DROP TABLE members_test4; GO
이렇게 테스트 테이블을 DROP TABLE 구문으로 삭제합니다.
SQL 강좌 책 구매
강좌가 도움이 되셨다면, 책으로 구매 가능합니다. 책 판매 수익금은 전액 코딩 교육 사회공헌 활동에 기부되며, 아래 링크에서 구매하시면 더 많은 금액이 기부됩니다.