본문 바로가기
클라우드 활용 자바개발자 양성과정/02. 데이터베이스 활용

07_DML(INSERT, UPDATE, DELETE)

by moca7 2024. 7. 23.

ㅁ < DML >

- Data Manipulation Language 데이터 조작어

- 데이터값을관리(삽입, 수정, 삭제)하는 언어

- INSERT(삽입), UPDATE(수정), DELETE(삭제)

 

 

ㅁ INSERT

- 테이블에 새로운 행을 추가하는 구문. (행단위로 추가가 된다)

 

 

(1) 테이블의 모든 컬럼값을 제시해서 한 행 추가

 

INSERT INTO 테이블명 VALUES (값, 값, 값, ... );

 

- 테이블에 존재하는 컬럼의 순서대로 모든 값을 작성해야 한다.

 

 

INSERT INTO EMPLOYEE VALUES ( 900, '이춘향', '980918-2222211', 'jang_ch@br.com', '01011112222,

                                                              'D1', 'J7', 4000000, 0.2, 200, SYSDATE, NULL, DEFAULT);

 

- ENT_YN은 DEFAULT가 'N'으로 설정되어 있다.

 

 

 

(2) 특정 컬럼만 선택한 후 값을 제시해서 한 행 추가

 

INSERT INTO 테이블명(컬럼명, 컬럼명) VALUES (값, 값);

 

- 데이터는 한 행 단위로 추가되기 때문에, 선택하지 않은 컬럼에는 DEFAULT값(설정되어 있다면)이나 NULL이 삽입됨.

 

- NOT NULL 제약조건이 부여되어 있는 컬럼은 DEFAULT값이 등록되어있지 않다면 반드시 값을 제시해야 함.

( = NOT NULL이어도 DEFUALT값이 설정되어 있으면 값을 제시하지 않아도 됨)

 

 

INSERT INTO EMPLOYEE(EMP_ID, EMP_NAME, EMP_NO, JOB_CODE, HIRE_DATE) VALUES ( 901, '이로은', '870123-2223412', 'J7', SYSDATE);

 

 

 

 

- 가독성을 위해 이렇게 쓰기도 한다. 컴마는 항상 내려주는 게 좋다. 

 

 

 

(3) 서브쿼리 수행 결과값을 통채로 추가하기 (한 행 x 여러 행)

- 서브쿼리는 다양한 곳에서 다 사용할 수 있다.

 

 

INSERT INTO 테이블명 [(컬럼명, 컬럼명)]  서브쿼리;           //       VALUES 없음.

 

 

- 컬럼을 선택할 수도 있고 선택하지 않을 수도 있다. (1번, 2번 방법 다 가능)

 

 

ㅇ EMPLOYEE 테이블의 전체 사원들의 사번, 이름, 부서명을 조회해서 EMP_01 테이블에 일괄등록

 

 

- 서브쿼리로 세 개의 컬럼을 넣는데, EMP_01에도 세 컬럼만 있어서 컬럼명 안 써도 됨. 

- EMP_01 테이블은 제약조건이 없어서 저 INSERT 문을 실행하면 똑같은 데이터가 계속 중복해서 삽입됨.

 

 

 

(4) 한 서브쿼리의 결과값을 두 개 이상의 테이블에 추가하기

 

 

INSERT ALL INTO 테이블1 [(컬럼명, 컬럼명, ...)] [VALUES (서브쿼리결과값컬럼, ...)]

                     INTO 테이블2 [(컬럼명, 컬럼명, ...)] [VALUES (서브쿼리결과값컬럼, ...)]

                     서브쿼리;

 

 

- 만약 서브쿼리 결과값의 모든 컬럼을 넣을 거면 VALUES도 생략 가능

 

 

 

 

(5) 서브쿼리 결과값 중 특정 조건에 만족하는 값만을 각 테이블에 추갛기

 

 

INSERT ALL WHEN 조건1 THEN INTO 테이블1 [(컬럼명, 컬럼명, ...)] [VALUES (서브쿼리결과값컬럼, ...)]

                       WHEN 조건2 THEN INTO  테이블2 [(컬럼명, 컬럼명, ...)] [VALUES (서브쿼리결과값컬럼, ...)]

                      서브쿼리;

 

 

- 모든 컬럼에 다 대입할거라 '테이블 다음 컬럼명' 안 썼고, 서브쿼리 결과값 컬럼 전부를 대입할거라 'VALUES (서브쿼리결과값컬럼)' 안 썼음.

 

 

 

(6) INSERT할 컬럼값으로 서브쿼리 결과값 작성 가능

 

 

INSERT ~~~ VALUES(값, 값, ..., 서브쿼리)

 

 

 

- VALUES 안에도 서브쿼리를 쓸 수 있다.

단, 한 개의 값만 조회되는 단일행 서브쿼리여야 한다. 

- 이렇게 쓰는 경우도 더러 있다. 

 

 

- 서브 쿼리 결과값에다가 산술연산을 해서도 넣을 수 있다. 

 

 

 

===========================================================================================

 

 

ㅁ UPDATE

- 테이블에 기록되어있는 기존 데이터를 수정하는 구문

- UPDATE는 한번에 한 테이블만 변경 가능.

 

UPDATE 테이블명 SET  컬럼명 = 바꿀값

                                      , 컬럼명 = 바꿀값

                                      , 컬럼명 = 바꿀값

                                      , ... 

                               [WHERE 조건] ;

 

- WHERE 절은 필수는 아니고 생략이 가능하다 

그런데 조건은 쓰는 것이 좋음. 전체 행의 모든 컬럼값이 다 변경되어서 웬만하면 조건 쓴다.

 

 

ㅇ 실습용 테이블 생성

 

 

- WHERE 조건을 안 쓰면 모든 행의 저 컬럼값이 '전략기획팀'이 됨.

 

 

 

 

 

ㅇ 실습용 테이블 생성

 

CREATE TABLE EMP_SALARY AS SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY, BONUS
                                                            FROM EMPLOYEE;

 

 

- 노옹철 사원의 급여를 100만원으로 변경

 

UPDATE EMP_SALARY SET SALARY = 1000000
                                        WHERE EMP_NAME = '노옹철';

 

 

- 선동일 사원의 급여를 700만원으로, 보너스는 0.2로 변경

 

UPDATE EMP_SALARY  SET  SALARY = 7000000
                                                 , BONUS = 0.2
                                          WHERE EMP_NAME = '선동일';

 

 

- 전체 사원의 급여를 기존의 급여의 10% 인상한 금액으로 변경

 

UPDATE EMP_SALARY  SET  SALARY = SALARY * 1.1;

 

 

 

ㅁ 번외) UPDATE문에 서브쿼리 활용

- SET절 뿐만 아니라 WHERE절에도 가능.

 

 

UPDATE 테이블명 SET 컬럼명 = (서브쿼리)

                               [WHERE 조건] ;           

 

 

ㅇ 방명수 사원의 급여와 보너스 값을 유내식 사원의 급여와 보너스 값으로 변경

 

 

UPDATE EMP_SALARY SET SALARY = (SELECT SALARY

                                                                    FROM EMP_SALARY

                                                                    WHERE EMP_NAME = '유재식')

                                               , BONUS = (SELECT BONUS

                                                                    FROM EMP_SALARY

                                                                    WHERE EMP_NAME = '유재식')

                                         WHERE EMP_NAME = '방명수' ;

 

 

UPDATE EMP_SALARY SET (SALARY, BONUS) = (SELECT SALARY, BONUS

                                                                                    FROM EMP_SALARY

                                                                                    WHERE EMP_NAME = '유재식')

                                         WHERE EMP_NAME = '방명수' ;

 

- 두가지 방법의 결과는 동일하다.

 

 

 

ㅇ ASIA 지역에 근무하는 사원들의 보너스를 0.3으로 변경

- L1이 ASIA1, L2가 ASIA2, L3가 ASIA3

 

UPDATE EMP_SALARY SET BONUS = 0.3

                                         WHERE EMP_ID IN ( SELECT EMP_ID 

                                                                             FROM EMP_SALARY

                                                                             JOIN DEPARTMENT ON DEPT_CODE = DEPT_ID

                                                                             JOIN LOCATION ON LOCATION_ID = LOCAL_CODE

                                                                             WHERE LOCAL_CODE IN ('L1', 'L2', 'L3) ) ;

 

- WHERE LOCAL_CODE IN ('L1', 'L2', 'L3) 대신 WHERE LOCAL_NAME LIKE 'ASIA%'도 똑같다.

 

 

ㅁ UPDATE시 제약조건 유의

 

 

ㅇ EMPLOYEE 테이블에서 사번이 200번인 사원의 이름을 NULL로 변경

 

UPDATE EMPLOYEE SET EMP_NAME = NULL

                                    WHERE EMP_ID = 200;

 

- 오류. EMP_NAME은 NOT NULL 제약조건이라 NULL로 못준다.

 

ㅇ 노옹철 사원의 직급을 J9로 변경

 

UPDATE EMPLOYEE SET JOB_CODE = 'J9'
                                    WHERE EMP_NAME = '노옹철';

 

- 오류. parent key not found. JOB_CODE는 외래키 설정되어 있는데 J9 부모 테이블 JOB에 없다. 

 

 

 

===========================================================================================

 

 

ㅁ DELETE

- 테이블에 기록된 데이터를 행 단위로 삭제하는 구문

 

 

DELETE FROM 테이블명 [WHERE 조건] ;

 

 

- WHERE 조건 생략 가능하지만 생략하면 전체 행이 다 삭제된다.

 

 

 

ㅇ EMPLOYEE 차태연 사원 삭제

 

DELETE FROM EMPLOYEE 

               WHERE EMP_NAME = '차태연' ;

 

 

 

ㅇ DEPT_ID가 D1인 부서 삭제

 

DELETE FROM DEPARTMENT

               WHERE DEPT_ID = 'D1' ;

 

- 오류. DEPARTMENT가 부모 테이블, EMPLOYEE가 자식 테이블이라서

D1값을 참조하고 있는 자식 데이터가 있으면 부모 테이블의 데이터를 삭제할 수 없다.

(삭제 제한 옵션은 따로 지정 안해서 기본값이다.)

 

 

- 외래키 제약조건으로 데이터 삭제가 불가능한 경우, (잠시) 제약조건을 비활성화할 수 있음.

그러려면 제약조건명이 필요함. 

 

 

- DEPT_CODE에 걸려있는 제약조건 FK의 이름은 SYS_C007157이다.

- 비활성화 되어있는지는 STATUS에서 확인할 수 있다.

 

 

 

 

 

 

- ALTER TABLE EMPLOYEE DISABLE CONSTRAINT SYS_C007157 CASCADE;

이러면 ENABLED가 DISABLED가 됨. 

 

- 부모 테이블 DEPARTMENT에서 D1인 데이터가 전부 삭제되었다.

자식 테이블 EMPLOYEE에는 D1이 그대로 있다. 

 

- 다시 ENABLE 하려고 하면 오류 뜬다. 자식 테이블의 DEPT_CODE에는 D1이 있는데,

부모 테이블의 DEPT_ID에는 D1이 없기 때문.

 

- ROLLBACK을 해도 DEPARTMENT에 D1이 돌아오지 않는다.

항상 ROLLBACK이 되는 것은 아니다.

 

 

 

- 롤백이 안되니 그냥 한 행 삽입하고, SYS_C007157 외래키(DEPT_CODE에 걸려있는 제약조건)를 ENABLE 시키면 잘 된다.

(EMPLOYEE 테이블의 제약조건 탭에서 SYS_C007157 FK의 STATUS가 ENABLED되었는지 확인 가능)

 

 

 

 

ㅁ TRUNCATE

- DDL

- 테이블의 전체 행을 삭제할 때 사용되는 구문.

- ROLLBACK이 불가능해서 DELETE보다 수행속도가 빠르다.

- 별도의 조건 제시 불가.

 

 

TRUNCATE TABLE 테이블명; 

 

 

- "Table EMP_SALARY이(가) 잘렸습니다."라고 나옴.

- ROLLBACK 해도 데이터 복구가 안 됨. 테이블은 있음. 

 

 

 

 

ㅁ COMMIT하면 그 순간부터 ROLLBACK 안 됨. 

- COMMIT을 하면 해당 트랜잭션에서 수행한 모든 변경 사항이 영구적으로 데이터베이스에 반영됩니다.