[DML]INSERT, UPDATE, DELETE

EUNJI LEE·2023년 4월 10일
1

SQL

목록 보기
7/14

DML

Date Manipulation Language의 약자로 테이블에 저장된 데이터(ROW)를 다루는 명령어를 말한다. INSERT, UPDATE, DELETE가 있다.

INSERT

테이블에 새로운 행을 추가하여 테이블의 ROW(행) 개수를 증가 시키는 구문이다. INSERT INTO 테이블명[(컬럼명)] VALUES (컬럼명1, 컬럼명2, …); 형태로 작성하며 컬럼 전체 데이터를 집어넣을 땐 중괄호[ ] 안은 생략 가능하다.

단, 테이블명 뒤 소괄호( ) 안에 특정 컬럼만 작성하는 경우 제외된 컬럼이 NULL값을 허용하는 컬럼이여야한다.

CREATE TABLE TEMP_DEPT
AS SELECT * FROM DEPARTMENT WHERE 1=0;
SELECT * FROM TEMP_DEPT;
INSERT INTO TEMP_DEPT VALUES('D0','JAVA','L1');
--INSERT INTO TEMP_DEPT VALUES('D1','ORACLE');
-->⚠️SQL 오류: ORA-00947: 값의 수가 충분하지 않습니다

--컬럼 지정해서 값 대입
DESC TEMP_DEPT;
INSERT INTO TEMP_DEPT(DEPT_ID,LOCATION_ID) VALUES('D2','L2');

💡 DESC
Describe의 약어로, 특정 테이블에 어떤 칼럼이 있는지 조회하는 명령어이다.

💡 CREATE TABLE 테이블명 AS SELECT문 을 작성하면 AS 뒤에 작성한 SELECT문으로 가져온 테이블을 복사할 수 있다. SELECT문 안에 WHERE절을 넣어 TRUE인 값을 주면 해당 조건의 TRUE인 값만 불러온다. 위의 경우처럼 어떤 경우에도 FALSE를 반환하는 조건식을 만드는 경우 해당 테이블의 ROW는 하나도 가져오지 않기 때문에 형식만 복사해온다.
이 때, 테이블을 복사해서 가져오는 경우 제약 조건은 NOT NULL 하나만 가져온다.

INSERT에 서브 쿼리 활용

테이블의 컬럼 자체를 복사해서 저장하는 개념이라고 볼 수 있다. 컬럼 값을 개별로 넣는 것이 아니기 때문에 VALUES로 구분해서 작성하지 않는다. 서브 쿼리의 컬럼 수는 대입할 컬럼 수와 동일해야 한다.

WHERE절을 사용하면 해당 조건식을 만족하는 데이터들만 불러와서 값을 저장할 수 있다.

CREATE TABLE INSERT_SUB
AS SELECT EMP_ID, EMP_NAME, DEPT_TITLE
FROM EMPLOYEE JOIN DEPARTMENT ON DEPT_CODE=DEPT_ID WHERE 1=2;

SELECT * FROM INSERT_SUB;
INSERT INTO INSERT_SUB(
--급여가 300만원 이상인 사원들의 정보만 저장
    SELECT EMP_ID, EMP_NAME, DEPT_TITLE
    FROM EMPLOYEE JOIN DEPARTMENT ON DEPT_CODE=DEPT_ID
    WHERE SALARY>=3000000
);
💡 서브 쿼리를 사용해도 특정 컬럼에만 값을 저장할 수 있다. 마찬가지로 NOT NULL 제약 조건이 없는 컬럼만 제외해서 선택할 수 있다.
INSERT INTO INSERT_SUB(EMP_ID, EMP_NAME)(SELECT EMP_ID, EMP_NAME FROM EMPLOYEE);

INSERT ALL

SELECT문 이용해서 두 개 이상의 테이블에 값을 넣을 때 사용한다. 동일한 데이터가 겹치지만 다른 데이터들을 각각의 테이블을 분할하는 경우에 사용할 수 있다. INSERT문 하나로 테이블에 저장할 데이터를 알아서 나눠서 저장할 수 있다는 장점이 있다.

CREATE TABLE EMP_HIRE_DATE
AS SELECT EMP_ID, EMP_NAME, HIRE_DATE FROM EMPLOYEE WHERE 1=0;
CREATE TABLE EMP_MANAGER
AS SELECT EMP_ID, EMP_NAME, MANAGER_ID FROM EMPLOYEE WHERE 1=0;

--입사년도가 있는 테이블과 매니저아이디가 있는 테이블
INSERT ALL
INTO EMP_HIRE_DATE VALUES(EMP_ID, EMP_NAME, HIRE_DATE)
INTO EMP_MANAGER VALUES(EMP_ID, EMP_NAME, MANAGER_ID)
SELECT EMP_ID, EMP_NAME, HIRE_DATE, MANAGER_ID
FROM EMPLOYEE;

--EMPLOYEE에서 00년 이전 이전 입사자는 EMP_OLD에 이후는 EMP_NEW에 저장
INSERT ALL
    WHEN HIRE_DATE<'00/01/01' THEN INTO EMP_OLD VALUES(EMP_ID,EMP_NAME,HIRE_DATE)
    WHEN HIRE_DATE>='00/01/01' THEN INTO EMP_NEW VALUES(EMP_ID,EMP_NAME,HIRE_DATE)
SELECT EMP_ID, EMP_NAME, HIRE_DATE
FROM EMPLOYEE;

UPDATE

UPDATE 테이블명 SET 수정할컬럼명=수정할값, ... [WHERE 조건식]; 형태로 작성한다. WHERE절은 생략해도 프로그램 상의 오류가 발생하지 않지만 작성하지 않으면 전체 컬럼 데이터가 변경된다. 때문에 반드시 WHERE절을 사용해서 수정할 데이터 타겟을 정확하게 구분해야 한다.

CREATE TABLE EMP_SALARY
AS SELECT EMP_ID, EMP_NAME, DEPT_CODE, JOB_CODE, SALARY, BONUS
FROM EMPLOYEE;
SELECT * FROM EMP_SALARY;
--전형돈의 급여를 300만원으로 수정
UPDATE EMP_SALARY SET SALARY=3000000 WHERE EMP_NAME='전형돈';
--다수의 컬럼 값 수정은 쉼표로 구분
UPDATE EMP_SALARY SET SALARY=2500000,BONUS=0.5 WHERE EMP_NAME='전형돈';
--다수의 ROW와 컬럼을 수정
--부서가 D5인 급여를 100000원씩 추가
UPDATE EMP_SALARY SET SALARY=SALARY+100000 WHERE DEPT_CODE='D5';

--UPDATE문에서 SELECT문 사용
--방명수의 부서,보너스를 심봉선과 동일하게 수정
UPDATE EMP_SALARY SET DEPT_CODE=(SELECT DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME='심봉선'),
                    BONUS=(SELECT BONUS FROM EMPLOYEE WHERE EMP_NAME='심봉선')
WHERE EMP_NAME='방명수';
SELECT * FROM EMP_SALARY WHERE EMP_NAME IN('방명수','심봉선');
💡 잘못 실행한 경우 `ROLLBACK`을 이용하면 `COMMIT`전까지 작성한 UPDATE문을 전부 되돌려준다. UPDATE문은 실행하고 나서 COMMIT전까지 하나의 트랜잭션으로 묶인다.

DELETE

테이블에 있는 ROW를 삭제하는 명령어DELETE FROM 테이블명 [WHERE 조건식]; 형태로 작성한다. 마찬가지로 WHERE절은 생략해도 프로그램 상 오류가 발생하지 않지만 WHERE 사용 안 하면 테이블에 있는 ROW가 전부 삭제된다.

DELETE로 삭제하고 COMMIT하면 되돌릴 수 없기 때문에 보통 컬럼 뒤에 플래그 함수를 넣은 컬럼을 만들어준다. DB상에는 데이터가 남아있을 수 있도록 관리한다.

--D9인 부서원들 삭제
DELETE FROM EMP_SALARY WHERE DEPT_CODE='D9';
SELECT * FROM EMP_SALARY;
ROLLBACK;

--DELETE FROM EMP_SALARY; >ROW 전체 삭제

TRUNCATE

ROLLBACK이 아예 불가능한 삭제 명령어이다. 실행하는 순간 삭제되기 때문에 DELETE보다 실행 속도가 빠르다는 장점을 갖지만 동시에 데이터를 되돌릴 수 없다는 단점이 있기 때문에 사용 시 주의해야 한다.

TRUNCATE TABLE EMP_SALARY;
profile
천천히 기록해보는 비비로그

1개의 댓글

comment-user-thumbnail
2023년 4월 13일

잘 봤습니다! 감사합니다!

답글 달기