본문 바로가기
공부/Oracle

오라클 SQL 문법 공부21- INSERT 문과 COMMIT, ROLLBACK

by 리빈아빠 2018. 3. 21.
반응형

서론

오랜만에 오라클에 관련되서 글을 작성하는 것 같다. 이것저것 준비하느라 한동안 손을 놓았는데 조금씩 오라클에 관해서도 계속해서 올려볼까 한다. 이번에는 SELECT 이후에 데이터를 입력하는 INSERT문에 대해서 알아보고자 한다.

본론

오다이바

-- INSERT
-- INSERT 명령어는 테이블에 새로운 데이터를 입력할 때 사용하는 명령어입니다.
-- 데이터를 입혁할 때 숫자 값 이외에는 데이터를 '(홑따옴표)로 감싸야 합니다.
-- 1)INSERT 를 사용하여 단일 행 입력하기
-- 문법
-- INSERT IN TO TABLE[(COL1, COL2...)]
-- VALUES(VALUE1, VALUE 2.....);

-- 1. 테이블의 전체 컬럼에 대한 값을 입력할때
-- INSERT INTO TABLE_NAME VALUES(VA1, VA2..)
-- EX) 
INSERT INTO EMP_TEST VALUES(9999, 'HONG', 'PRESIDENT', 7902, SYSDATE, 6000, 2000, 30);
-- COMMIT;

-- 2. 테이블의 컬럼을 선택적으로 입력할때
-- INSERT INTO TABLE_NAME(CO1, CO2..) VALUES(VA1, VA2, ...);

-- EX) 
INSERT INTO EMP_TEST(EMPNO, ENAME, HIREDATE) VALUES(9998,'PARK', '1988-09-09');
-- ROLLBACK;

-- 오렌지 날짜포맷과 동일해서 위에는 정상적으로 들어가버림
INSERT INTO EMP_TEST(EMPNO, ENAME, HIREDATE) VALUES(9998,'PARK', '09-09-1988');
-- 포맷이 다르니 안 들어감
-- 따라서 alter session set nls_date_format = 'YY-MM-DD HH24-MI-SS';
-- 날짜 포맷을 해당 날짜 타입에 맞게 수정 한 후 진행 하면 됨

-- 3. 특정 테이블에서 값을 가져와서 입력할때
-- INSERT INTO TABLE_NAME(COL1, COL2...)
-- SELECT COL1, COL2, ... FROM TABLE_NAME

-- EX) EMP_TEST 테이블에 EMP 테이블의 DEPTNO 가 10인 직원들의 전체 정보 입력
--
--INSERT INTO EMP_TEST
--SELECT * FROM EMP WHERE DEPTNO = 10;
--
-- EX) EMP_TEST 테이블에 EMP 테이블의 DEPTNO가 20인 직원들의 EMPNO, ENAME, DEPTNO 정보만 입력
--
INSERT INTO EMP_TEST(EMPNO, ENAME, DEPTNO)
SELECT EMPNO, ENAME, DEPTNO
FROM EMP WHERE DEPTNO = 20;

-- INSERT ALL 아래 형식으로 하면되는데 문법상 마지막에 무조건 SELECT절이 들어와야 된다.
-- 그래서 그냥 SELECT * FROM DUAL; 식으로 의미없는 구문을 넣어주면 된다. 
INSERT ALL
INTO EMP_TEST(EMPNO, ENAME, HIREDATE) VALUES(9998,'PARK', '09-09-1988')
INTO EMP_TEST2(EMPNO, ENAME, HIREDATE) VALUES(9998,'PARK', '09-09-1988')
INTO EMP_TEST3(EMPNO, ENAME, HIREDATE) VALUES(9998,'PARK', '09-09-1988')
SELECT * FROM DUAL;


INSERT 문은 새로운 데이터를 테이블에 저장할 때 사용하는 구문이다. INSERT INTO 테이블명('컬럼명') VALUES('해당컬럼에 들어갈 데이터'); 형식으로 작성한다. 단 테이블의 모든 컬럼에 값을 입력할 때에는 앞에 컬럼명을 무시하고 VALUES에 컬럼 순서에 맞게 차례대로 모든 컬럼에 대한 값을 입력하면 오류없이 입력이 가능하다. 컬럼 순서는 기존에 테이블을 생성할 때 정한 컬럼 순이다. 정확한 컬럼 순서를 모르겠다면 DUAL로 SELECT 해보거나 DESC 테이블명; 을 하여 나온 순으로 차례대로 입력하면 된다.


당연한 말이지만 앞에 특정 컬럼에만 값을 입력하고 싶어서 컬럼명을 명시하고 뒤에 값을 입력해주고 INSERT를 하였으나 오류가 나는 이유는 보통 해당 테이블에 기본키 혹은 NOT NULL, 참조키 등의 제약조건이 설정되어 있어서 이다. 예를 들어 특정 테이블의 제약조건이 기본키 한 가지가 있는데 이 기본키는 중복이 되어서 안되고, NOT NULL 비어있으면 안 되는데 해당 컬럼을 무시하고 나머지 컬럼에 대해서만 INSERT를 한다면 기본키 제약조건에 걸려서 (NOT NULL이기 때문에 반드시 값이 입력되어야 한다) INSERT문이 실행되지 않는 다는 것이다. 따라서 INSERT를 하기전에 어떤 컬럼들이 있는지, 어떤 제약조건들이 설정되어 있는지 잘 확인하고 진행하는 것이 좋다. 이 제약조건들에 대해서는 추후에 다른 문법 쪽에서 다루겠다.

COMMIT 과 ROLLBACK

위의 INSERT문 쿼리들을 잘 살펴보면 중간에 COMMIT; 과 ROLLBACK; 이 존재한다. COMMIT은 INSERT나 UPDATE, DELETE 한 내용들을 확실하게 DB에 쓰겠다 라고 확정을 하는 경우에 사용되고 ROLLBACK은 해당 내용을 취소하여 쓰지 않겠다라는 명령어이다.


사실 INSERT 문을 날린다고 즉시 DB에 데이터가 저장되는 것은 아니다. INSERT문을 날리고 즉시 SELECT 해보면 DB에 저장이 되어 있는 것 처럼 해당 데이터가 보이긴 하지만 실제 DB인 디스크에는 아직 기록이 되지 않은 상황이다. 나중에 오라클 구조에 대해서 공부하면 알겠지만 COMMIT; 을 날리고 나서 오라클 프로세스 중 하나인 DBWR가 메모리 위에 올라가 있는 DB 버퍼캐시에 있는 내용을 직접 DB로 쓰기 전까지에는 SELECT를 할 경우 DB 버퍼캐시의 데이터를 보여주는 것이다. 즉 COMMIT을 해야 디스크에 기록이 되고 ROLLBACK을 하면 디스크에 기록하지 않는다.


A사용자가 INSERT 후 COMMIT; 하지 않고 대기 중에 B 사용자가 같은 테이블을 조회해보면 A사용자와 B사용자가 조회한 내용이 다르다. RDBMS에서는 읽기 일관성이라 해서 A사용자가 INSERT 후 COMMIT을 찍지 않는다면 다른 사용자들은 A사용자가 INSERT 하기 전 데이터가 조회가 되고 해당 테이블은 락이 걸려서 A사용자가 COMMIT나 ROLLBACK을 하기 전까지는 다른 사용자가 해당 테이블을 조정할 수는 없다.


좀 더 자세한 이론적인건 나중에 오라클 구조 등의 공부 부분에서 다루겠고 문법공부하는 입장에선 COMMIT은 INSERT, UPDATE, DELETE 문을 실제 디스크인 DB에 쓰고 싶을 경우에 사용되고 DB에 쓰지 않고 취소 하고 싶다면 ROLLBACK을 해주면 된다.    

결론

INSERT문에 대해 알아보았다. 사실 단순히 문법만 공부하면 쉬운 부분인데 왜 오류가 나는지? 왜 이렇게만 해야되는지에 대해 의문을 품는다면 당연히 오라클 내부구조에 대해서 알아야 한다. 오라클 내부 구조를 안다면 해당 문법들을 더 쉽게 이해하고 외울 수 있을 거라 생각한다. 나중에 내부 구조들도 공부하면서 차근차근 올려보도록 하겠다.