[Oracle] 오라클 - DML ( 데이터 추가 INSERT/서브쿼리/다중행 추가)
by mini_min[Oracle]
오라클 - DML ( 데이터 추가 INSERT/서브쿼리/다중행 추가)
✔️ 데이터 조작언어(DML)
DML 은 데이터를 처리할 수 있게 하는 도구다.
✨ 롤백이 가능하다는 특징이 있다.
✨ 트랜잭션이란?
데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업 단위
또는 한번에 모두 실행되어야하는 일련의 연산들이다.
- 하나의 트랜잭션은 커밋되거나 롤백된다.
- 될거면 다 되던가, 안되려면 다 하지말기
- 오라클은 INSERT, UPDATE, DELETE 실행하면 자동 완료된게 아니므로 커밋이나 롤백해줘야한다.
❤️ 무조건 COMMIT or ROLLBACK 해줘야한다. (깨알 = DDL은 자동 커밋)
✔️ INSERT (데이터 삽입)
INSERT 는 데이터를 삽입할 때 사용하는 함수로, 단일행을 입력한다.
-- 기본형식
이때, 컬럼 순서가 매우 중요하다.
INSERT INTO 테이블명 VALUES (값, 값); INSERT INTO 테이블명 (컬럼, 컬럼) VALUES (값, 값); INSERT INTO test1 VALUES (2, '너자바', '2001-05-10'); -- 에러. 컬럼 개수와 값의 개수가 다름
💡 모든 컬럼에 값을 추가할 때는 컬럼명을 생략할 수 있다.
단, 테이블을 만들 때의 컬럼 순서로 값을 입력 해야한다.
❌ 컬럼 개수와 값의 개수가 다르면 입력 불가
❌ 컬럼 타입에 맞지 않는 값은 삽입 불가
** 날짜 형식 오류면 값 삽입 안된다. INSERT INTO test1 (num, name, birth, memo) VALUES (5, '하하하', TO_DATE('05/05/90', 'MM/DD/RR'), '테스트');
❌ 기본키 컬럼에는 반드시 NULL 이 아닌 값이 들어가야한다. (중복도 불가)
INSERT INTO test1 (num, name, birth, memo) VALUES (2, '노노노', '2001-05-10', '테스트'); -- ORA-00001: 무결성 제약 조건(SKY.SYS_C007476)에 위배됩니다 : 기본키 위반
❌ 컬럼 폭을 넘기는 값도 삽입 불가
INSERT INTO test1 (num, name, birth) VALUES (6, '노노노다다다고고고하하하', '2000-05-07'); -- 에러. ORA-12899 : 열에 대한 값이 너무 큼 (폭을 넘침)
🔒 문제
-- TIMESTAMP 컬럼 타입에 날짜/시간 추가하기
컬럼명 : reg_date
타입 : TIMESTAMP
ALTER TABLE test1 ADD reg_date TIMESTAMP;
-- 데이터 추가하기
num: 7, name : 이이이, birth : 2000-09-09, reg_date : 20220809154410200
INSERT INTO test1 (num, name, birth, reg_date) VALUES (7, '이이이','2000-09-09', TO_TIMESTAMP('20220809154410200', 'YYYYMMDDHH24MISSFF3'));
✔️ INSERT (subquery 이용)
subquery를 이용하면 다중 행 입력도 가능하다.
-- 기본형식
INSERT INTO 테이블명 [( 컬럼, 컬럼 )] SELECT 문;
INSERT INTO emp1 SELECT empNo, name, dept, pos FROM emp WHERE dept= '개발부';
💡 삽입할 테이블 명 뒤에 SELECT 절을 사용해서 부서명이 '개발부'인 사원번호/이름/부서명/직위를 emp1 테이블에 삽입할 수 있다.
✔️ INSERT ALL : 다중 테이블에 다중 행 추가
위에서 서브쿼리를 이용하면 단일 테이블에 다중 행을 추가할 수 있었는데, INSERT ALL 을 사용하면 한 번에 여러 테이블에 다중 행을 추가할 수 있다.
✨ 맨 뒤에 서브쿼리로 값 가져오기
-- 기본형식
INSERT ALL INTO 테이블명1 [( 컬럼, 컬럼 )] VALUES (수식1,수식2) INTO 테이블명2 [( 컬럼, 컬럼 )] VALUES (수식1,수식2) ... subquery;
CREATE TABLE emp2 AS SELECT empNo, name, dept, pos FROM emp WHERE 1 = 0; CREATE TABLE emp3 AS SELECT empNo, name, dept, pos FROM emp WHERE 1 = 0; INSERT ALL INTO emp2 (empNo, name, dept, pos) VALUES (empNo, name, dept, pos) INTO emp4 VALUES (empNo, sal, bonus) SELECT * FROM emp WHERE dept = '개발부';
💡 INSERT ALL INTO + 추가할 테이블 2개 각각
SELECT * FROM emp 에서 '개발부' 부서의 데이터를 가져올거다.
🔒 문제
만약, emp2 / emp4 테이블에 <7777 '후자바' '총무부' '직원' '2500000' '100000'> 값을 추가하고 싶다면?
INSERT ALL INTO emp2 (empNo, name, dept, pos) VALUES ('7777', '후자바', '총무부', '직원') INTO emp4 (empNo, sal, bonus) VALUES ('7777', 2500000, 100000) SELECT * FROM dual;
🔒 dual 테이블을 이용하면, 값 하나만 삽입할 수 있다.
만약, 위에처럼 '개발부' 조건으로 데이터를 삽입하면, '개발부' 데이터 갯수 만큼 데이터가 추가된다.
✔️ INSERT ALL : 조건 추가!
INSERT ALL 에 조건을 추가해서 다중 테이블에 다중 행 추가도 가능하다.
-- 기본형식
INSERT ALL WHEN 조건1 THEN INTO 테이블명1 [( 컬럼, 컬럼 )] VALUES (수식1,수식2) WHEN 조건2 THEN INTO 테이블명2 [( 컬럼, 컬럼 )] VALUES (수식1,수식2) ... ELSE INTO 테이블명n [( 컬럼, 컬럼 )] VALUES (수식1,수식2) subquery;
-- 남자 여자 분리해서 다중 데이터 추가하기
INSERT ALL WHEN MOD(SUBSTR(rrn,8,1),2) = 0 THEN INTO emp4 VALUES (empNo, name, rrn, dept, pos, sal, bonus) WHEN MOD(SUBSTR(rrn, 8,1),2) = 1 THEN INTO emp5 VALUES (empNo, name, rrn, dept, pos, sal, bonus) SELECT * FROM emp;
블로그의 정보
개발자 미니민의 개발로그
mini_min