a battle with myself

[ANSI SQL] 2. 데이터 삽입 (INSERT/INSERT SELECT/ SELECT INTO) 본문

sql

[ANSI SQL] 2. 데이터 삽입 (INSERT/INSERT SELECT/ SELECT INTO)

열공_중 2016. 8. 3. 10:16

Data 삽입

Insert 의 사용 용도

- 하나의 완전한 행을 삽입

- 하나의 부분적인 행을 삽입

- Query 결과를 삽입

 

열(field) 가 총 10개인 table 이 있다고 하자.

table 명 : Temp_Table

각 열(field) 이름 및 행(record)의 data

field1 

 field2

field3 

field4 

field5 

 field6

 field7

 field8

 field9

 field10

 data1

data1-2

data1-3 

data1-4 

data1-5 

data1-6 

data1-7 

data1-8 

data1-9 

data1-10 

 

완전한 record 의 삽입

 

INSERT INTO Temp_Table

VALUES('data2','data2-2','data2-3','data2-4','data2-5','data2-6','data2-7','data2-8','data2-9','data2-10');

INSERT 문에서는 Temp_Table  테이블에 각 필드에 순서대로 data2 에서 data2-10 값이 저장된다.

각 테이블 여레 저장될 값은 VALUES 절에 지정되어 있으며 모든 열의 값을 지정해야 한다.

해당 INSERT 문을 실행 하고 나면 테이블 값은 이렇게 저장되어있을것이다.

field1 

 field2

field3 

field4 

field5 

 field6

 field7

 field8

 field9

 field10

 data1

data1-2

data1-3

data1-4

data1-5

data1-6

data1-7

data1-8

data1-9

data1-10 

data2

data2-2

data2-3

data2-4

data2-5

data2-6

data2-7

data2-8

data2-9

data2-10 

 

위 INSERT 구문은 아주 간단하지만 안전하지 않고 여러 대가를 치러야 한다. 일단 테이블에 정의된 행(record)의 순서를 그대로 지켜야 한다는 점이 문제이고 이 순서 정보를 정확히 판단하고 있기가 힘들다는 점도 문제이다. 순서를 정확히 알고 지켰다고 해도 테이블의 구성을 변경했을 시 이 순서가 그대로 남아있을지에 대해서도 의문이다. 따라서 특정한 열순서에 의존하는 SQL 문을 작성하는 것은 안전하지 못하며 위험성이 크다.

다소 귀찮더라도 안전한 방식으로 INSERT 문을 작성하는 것이 좋다.

INSERT INTO Temp_Table(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10)

VALUES('data3','data3-2','data3-3','data3-4','data3-5','data3-6','data3-7','data3-8','data3-9','data3-10');

 

위의 Query문의 결과

field1 

 field2

field3 

field4 

field5 

 field6

 field7

 field8

 field9

 field10

 data1

data1-2

data1-3

data1-4

data1-5

data1-6

data1-7

data1-8

data1-9

data1-10 

data2

data2-2

data2-3

data2-4

data2-5

data2-6

data2-7

data2-8

data2-9

data2-10 

data3

 data3-2

 data3-3

data3-4

data3-5

data3-6

data3-7

 data3-8

data3-9

data3-10 

결과는 위의 실행 내용과 동일 하다.

테이블 명뒤에 나열된 열(field)명의 순서대로 VALUES 절에 지정된 값이 삽입 된다.

 

 

순서대로 짝을 이뤄 삽입 되기 때문에 열과 VALUES 절의 값의 순서만 같으면 나열 순이 틀려도 상관 없다.

 

INSERT INTO Temp_Table(field1, field2, field4, field3, field5, field6, field7, field8, field9, field10)

VALUES('data4','data4-2','data4-4','data4-3','data4-5','data4-6','data4-7','data4-8','data4-9','data4-10');

 

위의 Query문의 결과

field1 

 field2

field3 

field4 

field5 

 field6

 field7

 field8

 field9

 field10

 data1

data1-2

data1-3

data1-4

data1-5

data1-6

data1-7

data1-8

data1-9

data1-10 

data2

data2-2

data2-3

data2-4

data2-5

data2-6

data2-7

data2-8

data2-9

data2-10 

data3

 data3-2

data3-3

data3-4

data3-5

data3-6

data3-7

data3-8

data3-9

data3-10 

data4

data4-2 

 data4-3

data4-4

data4-5

data4-6

data4-7

data4-8

data4-9

data4-10

 

field3 번과 4번의 위치를 틀리게 했지만 VALUES 절에서 값도 위치에 맞게 넣어두었으므로 결과는 위의 실행 내용과 동일 하다.

 

 

부분 행(record) 삽입

 

INSERT 문을 사용할 때 권장되는 방법은 테이블 열 이름을 정확하게 지정해주는 것이다.

이 방법을 사용하면 일부 열에 값을 지정하지 않을 수도 있다. 즉 일부 열(field)에만 값을 지정하고 나머지 열에는 값을 지정하지 않아도 된다.

 

INSERT INTO Temp_Table(field1, field2, field5, field6, field7, field8, field9, field10)

VALUES('data5','data5-2','data5-5','data5-6','data5-7','data5-8','data5-9','data5-10');

 

위의 Query문의 결과

field1 

 field2

field3 

field4 

field5 

 field6

 field7

 field8

 field9

 field10

 data1

data1-2

data1-3

data1-4

data1-5

data1-6

data1-7

data1-8

data1-9

data1-10 

data2

data2-2

data2-3

data2-4

data2-5

data2-6

data2-7

data2-8

data2-9

data2-10 

data3

data3-2

data3-3

data3-4

data3-5

data3-6

data3-7

data3-8

data3-9

data3-10 

data4

data4-2 

 data4-3

data4-4

data4-5

data4-6

data4-7

data4-8

data4-9

data4-10

data5 

data5-2 

NULL

NULL

data5-5

data5-6

data5-7

data5-8

data5-9

data5-10

 위에 내용을 보면 INSERT INTO 구문에서도 field3,4번이 제외 되었고 VALUES 절에서도 data5-3,5-4의 값이 빠져있으므로 열(field) 3,4 번의 값이 NULL 값이 들어 간 걸 알 수 있다.

*주의 : 위의 결과에서 field3,4 은 테이블 생성 시 NULL 값이 들어가도록 설정 되어 있어야 한다. 기본키(primary key) 또는 NOT NULL 이 지정되 있는 열(field) 라면 구문 상의 오류가 뜬다.

NULL 값의 허용

- 테이블이 NULL 값을 허용하도록 정의되어야 한다. 즉 값이 없는 열이 있어도 되도록 구성되어 있어야 한다.

- 테이블 정의에 기본값이 정의 되어 있어야 한다.즉 값을 지정하지 않으면 대신 사용될 기본 값이 있어야한다. ex) DEFAULT 'a'

 

 

가져온 DATA 삽입(INSERT SELECT)

 

INSERT 는 대개 지정된 값을 사용하여 테이블에 행(record)을 추가 할대 쓰이지만 SELECT 문의 결과를 테이블에 삽입하는것도 가능하다.

이를 INSERT SELECT 라고 하며 이름이 말해주듯이  INSERT 문과 SELECT 문이 결합된 형태이다.

 

INSERT SELECT 구문을 사용하기 위해서는  DATA 를 가져오기 위한 table 이 존재 해야 한다.

 

 DATA를 삽입 할 테이블 : Temp_Table

field1 

 field2

field3 

field4 

field5 

 field6

 field7

 field8

 field9

 field10

 data1

data1-2

data1-3

data1-4

data1-5

data1-6

data1-7

data1-8

data1-9

data1-10 

data2

data2-2

data2-3

data2-4

data2-5

data2-6

data2-7

data2-8

data2-9

data2-10 

data3

data3-2

data3-3

data3-4

data3-5

data3-6

data3-7

data3-8

data3-9

data3-10 

data4

data4-2 

 data4-3

data4-4

data4-5

data4-6

data4-7

data4-8

data4-9

data4-10

data5 

data5-2 

NULL

NULL

data5-5

data5-6

data5-7

data5-8

data5-9

data5-10

 

data를 가져올 table : Sub_Table 

s_field1 

 s_field2

s_field3 

s_field4 

s_field5 

 s_field6

 s_field7

s_field8

s_field9

s_field10

s_data1

s_data1-2

s_data1-3

s_data1-4

s_data1-5

s_data1-6

s_data1-7

s_data1-8

s_data1-9

s_data1-10

s_data2

s_data2-2

s_data2-3

s_data2-4

s_data2-5

s_data2-6

s_data2-7

s_data2-8

s_data2-9 

s_data2-10

 

INSERT INTO Temp_Table(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10)

SELECT s_field1, s_field2, s_field3, s_field4, s_field5, s_field6, s_field7, s_field8, s_field9, s_field10

FROM Sub_table ;

 

실행 결과

Temp_Table

field1 

 field2

field3 

field4 

field5 

 field6

 field7

 field8

 field9

 field10

 data1

data1-2

data1-3

data1-4

data1-5

data1-6

data1-7

data1-8

data1-9

data1-10 

data2

data2-2

data2-3

data2-4

data2-5

data2-6

data2-7

data2-8

data2-9

data2-10 

data3

data3-2

data3-3

data3-4

data3-5

data3-6

data3-7

data3-8

data3-9

data3-10 

data4

data4-2 

 data4-3

data4-4

data4-5

data4-6

data4-7

data4-8

data4-9

data4-10

data5 

data5-2 

NULL

NULL

data5-5

data5-6

data5-7

data5-8

data5-9

data5-10

s_data1

s_data1-2

s_data1-3

s_data1-4

s_data1-5

s_data1-6

s_data1-7

s_data1-8

s_data1-9

s_data1-10

s_data2

s_data2-2

s_data2-3

s_data2-4

s_data2-5

s_data2-6

s_data2-7

s_data2-8

s_data2-9

s_data2-10

 

INSERT SELECT 문을 사용하여 Sub_TableDATATemp_Table에 삽입한다. VALUES 를 사용하여 일일이 지정할 필요 없이 Sub_Table 테이블의 모든 DATA를 가져와 삽입할 수 있다. SELECT 내의 각 열(field)은 앞서 지정된 열 목록과 대응 되어야 한다. 만약 Sub_Table 이 비어 있다면 삽입 작업이 이루어 지지않고 오류도 발생하지 않고 테이블에 DATA 가 있을 경우 모든 데이터가 Temp_Table에 삽입된다.

* 주의 : 만약 두 테이블 간에 기본키가 중복 된다면 실행 시 오류 가 발생한다.

* 응용 : SELECT 문에  WHERE 조건문을 추가 하여 원하는 데이터만 삽입 할수 도 있다.

 

 

테이블 복사(SELECT INTO)

INSERT 방식을 사용하지 않는 방식의 DATA 삽입 작업도 있다.

한 테이블의 내용을 새로운 테이블(즉시 생성)에 삽입 하려면 SELECT INTO 문을 사용한다.

 

INSERT SELECT 문은 기존 테이블에 DATA를 추가 하지만 SELECT INTODATA를 새 테이블에 복사해서 넣는다.

 

실행

SELECT * INTO Temp_Copy FROM Temp_Table;

 

 

이 SELECT 문은  Temp_Copy 라는 테이블을 새로 만들고 Temp_Table 의 모든 DATA를 복사하여 이 테이블에 삽입한다. 일부만 복사할려면 *  대신 원하는 열(field) 명을 직접 지정해주면 된다.

 

* 주의 : DB2 에서는 지원되지 않는다.

- MySQL 과 Oracle 에서는 구문이 약간 다르다.(CREATE TABLE Temp_Copy AS SELECT * FROM Temp_Table ;)

- WHERE 이나 GROUP BY 등과 같은 모든 SELECT 옵션을 사용할 수 있다.

- JOIN 을 사용하여 여러 테이블에서 데이터를 가져올 수 있다.

- 데이터를 가져오는 테이블의 개수에 관계없이 가져온 모든 데이터는 하나의 테이블에 삽입된다.

- 실제 DATA 를 가지고 하기에는 위험성이 있는 SQL 문이 있다면 복사본을 만들어 사용하는 것이 안전하고 SELECT INTO문은 복사 본을 만드는 아주 훌륭한 방법이다.

 

 

 

 

 

[ANSI SQL]1. SQL의 이해