2주 동안 DBMS를 빠르게 배웠다
정말 감잡고 이해한다고 풀어본 DQL문제만 몇개인지...더 이상의 출력은 멈춰!✋
But, 너무 재밌었고, 이제 JDBC로 연결해서 다룰 일만 남았다!
그런 의미에서 지난 2주동안 배운 걸 총 정리하는 시간을 가지고자 한다 :)
물론 오늘 배운 것도 추가되어 있음😼
여러 사람이 공유하고 사용할 목적으로 통합 관리되는 데이터 집합
중복된 데이터는 지양하고 데이터를 구조화해, 효율적 처리를 하고자 만들어졌고, 이를 조작하기 위해선 DBMS가 필요하다.
Data Base Management System
DBMS는 데이터베이스 내부의 데이터를 조작하고, 생성하기 위한 미들웨어
[ 특징 ]
1) 독립성 : 응용프로그램을 건드리지 않고, DB 사이즈나 데이터를 추가할 수 있다.
2) 무결성 : 특정 양식과 규격을 둠으로써 잘못된 데이터가 들어오는 걸 방지한다.
3) 보안성 : 계정이란 객체를 통해, 그 밑에 데이터를 보관한다. 접근 권한을 가진 사용자만 데이터 자원을 조작할 수 있다.
4) 중복 최소화 : 각 프로그램의 데이터를 통합 관리함으로써, 중복되는 데이터들을 줄일 수 있다.
Structured Query Language
DBMS 안에서 수행되는 명령어 체계를 말한다. 크게 4가지로 분류된다.
Data Definition Language
객체를 생성, 수정, 삭제하는 명령어
객체를 생성하는 명령어
[ 계정 생성 시 ]
create user OO identified by OO;
[ 테이블 및 객체 생성 시 ]
create table cafe(
컬럼명 자료형 제약조건
);
not null
데이터의 공백을 방지하기 위한 조건
[ 특징 ]
insert into
로 값을 입력하지 않으면 에러가 난다. not enough values
create table cafe(
pid number not null,
pname varchar(30) not null,
price number not null
);
[ 응용 ]
create table cafe(
pid number not varchar,
pname varchar(30) not number,
);
식별자 데이터의 중복을 막기 위한 조건
[ 특징 ]
not null
+ 중복 방지create table cafe(
pid number primary key — 컬럼 레벨 주키 설정
);
create table cafe(
pid number,
pname varchar(30) not number,
primary key(pid, pname) — 테이블 레벨 주키 설정
);
unique constraint (account.SYS_C007022) violated
데이터의 중복을 방지하기 위해 사용
[ 특징 ]
unique not null
로 사용하고 이는 primary key
와 같다.create table cafe(
pid number primary key,
pname varchar(30) unique not null,
price number unique not null
);
컬럼 안에 들어갈, 값을 통제
[ 특징 ]
check
로 설정하면 설정된 데이터만 넣을 수 있다.check + 조건식
create table cafe(
pid number primary key,
pname varchar(30) unique not null,
price number not null,
iced varchar(1) check (iced in ('Y', 'N')) not null
);
[ 특징 ]
primary key
unique
로 제약되어야 한다.create table product(
pid number primary key,
);
create table sales_history(
sid number primary key,
-- 컬럼명 references 테이블(부모컬럼)
pid references product(pid), -- 실행시, 부모 테이블로 가서 데이터 확인 및 입력
sdate date default sysdate not null
);
[ 주의 ]
부모 키를 삭제할 때, 문제가 발생하기 쉽다.
데이터 무결성을 위해 부모 키를 삭제하면 전 테이블 안에 그 값이 남아있으면 안 된다.
그러나, 자식 키에 그 값이 남는다. 따라서 부모 키를 삭제하기 위해선 3가지 방법이 있다.
① 외래키 제약조건을 없앤다. - references 제거
② 자식 레코드를 지운 뒤, 부모 레코드를 지운다.
③ 자식 테이블 자체를 재생성하고 옵션을 준다.
on delete cascade
: 부모 키 삭제 시, 연결된 자식 키도 함께 삭제create table sales_history(
sid number primary key,
pid references product(pid) on delete cascade,
sdate date default sysdate not null -- default 는 제약조건 앞에만 가능
);
on delete set null
: 부모 키 삭제 시, 모든 자식 키의 값을 null
로 세팅create table sales_history(
sid number primary key,
pid references product(pid) on delete set null,
sdate date default sysdate not null
);
객체를 수정하는 명령어
① alter – drop
: 기존 테이블의 컬럼을 삭제
alter table cafe drop column iced;
② alter – add()
: 기존 테이블에 컬럼을 추가
alter table cafe add(iced varchar(1) check(iced in ('Y', 'N')));
③ alter – modify
: 기존 테이블 컬럼의 정보를 수정
alter table cafe modify (iced varchar(5) not null);
-- not null을 줄 때는, 기존 컬럼에 공백이 없어야 한다.
④ alter - rename 기존명 to 수정명
: 기존 테이블의 컬럼의 이름을 수정
alter table cafe rename column price to pprice;
⑤ alter 객체유형 객체명 – rename
: 기존 테이블의 이름을 수정
alter table cafe rename to cafe_menu;
객체를 삭제하는 명령어
drop | 지울 객체 유형 | 객체명;
drop table cafe;
① 시스템 계정
② 사용자 계정
record (행- 가로) : 하나의 개체의 여러 정보
column (열- 세로) : 하나의 자료형에 대한 여러 개체 정보
[ 특징 ]
nocache
: 메모리에 미리 올려놓기 때문에 의도치 않은 값이 들어갈 수 있기 때문에 설정.
을 통해 메서드 활용이 가능하다.create sequence [시퀀스명]
start with [시작점] -- 예) start with 1 “1부터 시작”
increment by [증감숫자] -- 1씩 증가한다. (변경 가능)
maxvalue -- 최대값 || nomaxvalue — 최대값 없음
minvalue — 최소값 || nominvalue – 최소값 없음
nocache;
-- 활용
insert into cafe values(cafe_seq.nextval, 'Orange Juice', 4000, 'Y');
[ 예시 ]
grant create view to kh; -- view 생성 권한 (system)
grant select on sub_employee_view to test; -- test 계정에 권한 부여 (kh)
-- view 객체 생성
create view 객체명 as
컬럼1, 컬럼2, 컬럼3 ∙∙∙ from 참조테이블;
create view sub_employee_view as
select emp_id, emp_name, phone from employee;
-- view 객체 조회
select * from kh.sub_employee_view; -- test 계정
[ 원리 ]
[ 주의 ]
: 다음과 같은 경우는 View를 통해 DML을 수행할 수 없음.
1. 뷰 정의에 포함되지 않은 컬럼을 조작하는 경우
2. 뷰에 포함되지 않은 컬럼 중에 베이스가 되는 테이블 컬럼이 NOT NULL 제약조건이 지정된 경우
3. 산술 표현식으로 컬럼이 정의된 경우
4. JOIN을 이용해 여러 테이블을 연결한 경우
5. DISTINCT를 포함한 경우
6. 그룹 함수나 GROUP BY 절을 포함한 경우
Data Control Language
객체 또는 데이터에 대한 접근 권한을 생성, 수정, 삭제하는 명령어 체계
: 계정 생성 후, 해당 계정에 권한을 부여할 때 사용
grant 권한 to 계정명;
grant connect, resource to admin;
: 계정에 부여한 권한을 회수할 때 사용.
revoke 권한 from 계정명;
revoke select on employee from test; -- employee 테이블을 검색할 권한
: 다양한 권한의 묶음
connect : 오라클 DB에 접속하도록 하는 시스템 권한 묶음
resource : 객체 (생성, 수정, 삭제) 권한 묶음
Data Manipulation Language
데이터를 생성 / 수정 / 삭제하는 명령어
데이터를 조회할 때 사용
[ 기본 문법 ]
select < 컬럼명, 연산식, 리터럴, 서브쿼리 ···· > from 테이블명
[ 실행 순서 ]
select 5 from 1 where 2 group by 3 having 4 order by 6
: 데이터를 검색하여 가져오고 특정 양식으로 출력함.
: 데이터를 검색할 테이블을 지정한다.
: 전체 데이터에 대해 조건을 걸 때 사용
서브 쿼리, 조건식 등을 통해 조건문을 만들 수 있다.
between
: 특정 구간을 설정할 때 사용.select emp_name, salary from EMPLOYEE
where salary >= 300 and salary <= 400;
select emp_name, salary from EMPLOYEE
where salary between 300 and 400;
is null
: 해당 값이 공백인지 확인할 때 사용. (공백은 부등호로 계산되지 않는다)select * from employee where bonus is null;
select * from employee where bonus is not null;
or
연산자의 간략화이다.select emp_name, dept_code from EMPLOYEE
where dept_code='D2' or dept_code='D6';
select emp_name, dept_code from EMPLOYEE
where dept_code in ('D2', 'D6');
date
로 일수 계산하기 : sysdate
- 날짜 = 일수 (date – date = number)select emp_name, salary, bonus from EMPLOYEE
where floor(sysdate - hire_date) > 365*20;
% : %을 기준으로 이후 글자가 없을 수도 있고, 있을 수도 있다.
select * from employee where emp_name like '차%';
select * from employee where emp_name like '%연%'; -- '연'을 포함하는 데이터
select * from employee where emp_name like '%태'; -- '태'로 끝나는 데이터
select * from employee where emp_name like '노%'; -- '노'로 시작하는 데이터
_ : 정확한 한 글자가 존재한다.
select * from employee
where emp_name like '차__'; -- '차'로 시작, 2글자 존재 (검색 결과 O)
select * from employee
where emp_name like '차_'; -- '차'로 시작, 1글자 존재 (검색 결과 X)
: 특정 기준을 기반으로 데이터를 묶는다.
[ 특징 ]
그룹화된 데이터는 개별 출력 불가
select emp_name, dept_code from employee — emp_name X
group by dept_code;
그룹화된 해당 데이터 | 그룹 함수로 데이터 출력 가능
① 그룹화된 해당 데이터
select dept_code from employee group by dept_code;
② 그룹함수로 쓰인 데이터
select sum(salary) from employee group by dept_code;
조건 별로 그룹화 가능
select
case
when 나이 between 30 and 39 then '30대'
when 나이 between 40 and 49 then '40대'
when 나이 between 50 and 59 then '50대'
else '60대'
end 연령대,
count(*) 인원
from
employee
group by
case
when 나이 between 30 and 39 then '30대'
when 나이 between 40 and 49 then '40대'
when 나이 between 50 and 59 then '50대'
else '60대'
end;
--단, select에서 출력하는 데이터와 group by 로 묶은 양식이 일치해야 힌디.
: 그룹화된 데이터에 대한 조건을 걸 때 사용
[ 응용 ]
-- 부서별 급여합계가 1000만원 이하만 출력
select dept_code, sum(salary)
from employee
group by dept_code
having sum(salary)<10000000 --group by에 대한 조건문
order by 1;
: 검색한 데이터를 기준으로 정렬할 때 사용
[ 특징 ]
asc
⟷ desc
: 내림차순select emp_id, emp_name, salary
from employee; -- 기본
select emp_id, emp_name, salary from employee
order by 3; -- 숫자로도 설정가능
select * from employee
order by
dept_code, salary desc; -- dept_code 정렬 후, salary로 내림차순 정렬
: 여러 테이블의 데이터(행)를 조건으로 하나의 가상 테이블로 모으는 문법
반복문으로 따지면, 이중 for문에 조건을 걸어
여러 테이블의 레코드들을 하나로 묶어 운영하는 문법이다.
[ 원리 ]
select * from DEPARTMENT, Job; -- 오라클 문법
for Department
for job
// 굳이 표현하면 이런 느낌..
이렇게 출력되는 데이터는 의미가 없다.
의미가 있는 데이터를 위해 조건을 부여해 사용.
on
, where
을 통해 조건 부여[ 주의 ]
: 비교 컬럼 간의 이름이 같은 경우
as
로 구분해준다.employee (job_code) | job (job_code)
select
emp_name,
A.job_code,
job_name
from employee A
join job B
on (A.job_code=B.job_code) -- 확실하게 구분.
order by 1;
select
emp_name,
A.job_code,
job_name
from employee A
join job B using(job_code)
-- from employee A join job B on (A.job_code=B.job_code)와 같다.
order by 1;
[ 두 가지 문법 ]
select emp_id, emp_name, dept_title
from employee, department
where (dept_code=dept_id)
order by 1;
select emp_id, emp_name, dept_title
from employee join department on (dept_code=dept_id)
order by 1;
[ join의 종류 ]
조건이 없는 join
select * from DEPARTMENT, job;
의미 있는 데이터를 만드는 join
select emp_id, emp_name, dept_title
from employee (inner) join department on (dept_code=dept_id)
order by 1;
각 테이블의 데이터 생략을 막는 join
[ ANSI ]
select emp_id, emp_name, dept_title
from employee
left outer join department on (dept_code = dept_id);
오라클 : 값이 없는 테이블에 (+)을 추가해줌
select emp_id, emp_name, dept_title
from employee, department where dept_code = dept_id(+);
[ ANSI ]
select emp_id, emp_name, dept_title
from employee
right outer join department on (dept_code = dept_id);
오라클
select emp_id, emp_name, dept_title
from employee, department where dept_code(+) = dept_id;
[ ANSI ]
select emp_id, emp_name, dept_title
from employee
full outer join department on (dept_code = dept_id);
테이블 2개를 쓰는 것은 맞지만, 둘은 같은 테이블이다.
-- employee의 MANAGER_ID: 각 직원 별 직속 상사의 ID
select * from employee; join employee;
-- 자신이 관리하고 있는 사원의 이름, 급여 등을 출력하세요.
select
e1.emp_name, 상사의 이름
e2.emp_name, 직원의 이름
e2.salary 직원의 월급
from employee e1
join employee e2 on (e1.emp_id = e2.manager_id);
-- 그룹화 추가
select
e1.emp_name,
count(*),
sum(e2.salary)
from employee e1 join employee e2 on (e1.emp_id = e2.manager_id)
group by e1.emp_name;
-- 여러 개의 join도 가능
select
emp_name, dept_title, job_name
from employee e
left join department d on (dept_code = dept_id) -- 첫 번째 join
join job j on (e.job_code=j.job_code) -- 첫 join에 따른 두 번째 join
order by 1;
각 행 하나마다 적용되는 함수
select length('Hello') from dual; -- 문자열의 길이를 리턴 [5]
select lengthb('Hello') from dual; -- 영문자는 한 글자당 1바이트
select lengthb('한글') from dual; -- 한 글자당 3바이트
instr('문자열', '찾고자 하는 거', 전체 인덱스 중 시작점, 발견 시점);
select instr('Hello World Hi High', 'H', 1, 1) from dual;
substr('Now on Oracle practice',시작점, 시작포함 n개)
select substr('Now on Oracle practice',8,6) from dual;
select distinct substr(emp_name,1,1) from employee;
select replace('Hello Java', 'Java', 'oracle') from dual;
select replace(email, 'kh', 'iei') from employee;
select abs(-1) from dual;
select mod(10,2) from dual; -- 0
select mod(10,3) from dual; -- 1
select round(126.756, 소수점 기준 몇 번째 자리) from dual;
select round(126.756, -1) from dual; -- 130
select round(127.243, 1) from dual; -- 128.2
select trunc(123.456, 1) from dual; -- 123.4
select ceil(122.024) from dual; -- 123
select sysdate from dual;
select emp_name, hire_date, months_between(sysdate, hire_date)
from employee;
select add_months('22/03/17',6) from dual; -- 22/09/17
select sysdate, next_day('22/03/17', '토요일') from dual; --'22/03/19'
select last_day(sysdate) from dual;
select extract(year from sysdate) from dual;
select extract(month from sysdate) from dual;
select extract(day from sysdate) from dual;
select emp_name,extract(year from hire_date) from employee;
<날짜의 경우>
아스키 코드(/, -, .)를 넘어가는 양식에 대해선 “”을 통해서 설정해줘야 한다.
select to_char(sysdate, 'YYYY/MM/DD') from dual;
select
to_char(sysdate, 'YYYY-MM-DD HH:MI:SS') -- mm = MI
from dual;
select to_char(sysdate, 'YYYY"년 "MM"월 "DD"일" HH24:MI:SS') from dual;
<숫자의 경우>
1. 원본 데이터 개체보다 형식의 크기가 커야 한다. 작으면 깨진다.
2. L은 시스템 국가의 화폐 기호가 붙는다.
3. 9대신 0을 쓰면, 빈자리를 0으로 채워준다.
select emp_name, to_char(salary, 'L999,999,999') from employee;
select emp_name, to_char(salary, '000,000,000')||'원' from employee;
select to_date('2019년01월02일', 'YYYY"년"MM"월"DD"일"') from dual;
select to_date(1901020820, 'YYMMDDHHMI') from dual;
select
decode(substr(emp_no, 8, 1), 1, '남','여' )
from employee;
select
case
when 조건 then 결과
end
from employee;
특정 컬럼 전체에 한번에 적용되는 함수
select sum(salary) from
employee; --- 70096240
select to_char(sum(salary), 'L999,999,999')
from employee; --- ₩70,096,240
select round(avg(salary), 1) from employee;
select count(dept_code) from employee;
select count(*) from employee;
select max(salary) as "최고연봉" from employee;
위에서부터 순서를 붙히는 함수
: 공동순위 부여 가능, 공동순위 부여시 공백은 제거
select
emp_name,
salary,
rank() over(order by salary desc) 순위
from
employee;
: 공동순위를 부여하지만, 그로 인해 비는 값을 지우지 않는다.
select
emp_name,
salary,
dense_rank() over(order by salary desc) 순위
from
employee;
: 공동순위를 붙이지 않고, 행번호를 컬럼으로 빼는 용도로 사용된다.
select
emp_name,
salary,
row_number() over(order by salary desc) 순위
from
employee;
추가적으로 inline view랑 row_number()는 같이 쓰인다.
select * from
(select emp_name, salary, row_number() over(order by salary desc) 순위 from employee)
where
순위 between 1 and 5;
: 두 개 이상의 테이블을 합치는 건 같지만, 원리가 Join과 다르다.
종류 : `UNION` / `UNION ALL` / `INTERSECT` / `MINUS`
용도 : 데이터 양식은 똑같은데, 의미가 다른 경우. 전체 조회 시 사용.
: 중복되는 데이터는 한 번만 출력되게 병합.
select emp_id, emp_name, emp_no -- 3개
from employee
union
select * from department; -- 3개
select salary from employee -- 숫자
union
select dept_id from department; -- 문자
-- 병합 X
select * from tmp1
union
select * from tmp2;
: 중복되는 데이터까지 포함해 출력되게 병합
select * from tmp1
union all
select * from tmp2;
: 중복되는 데이터만 출력
select * from tmp1
intersect
select * from tmp2;
: 첫 번째 select 결과에서 두 번째 select 결과를 뺄셈하여 남는 첫 번째 데이터만 출력
select * from tmp1 ABC (중심은 첫번째)
minus
select * from tmp2; BCD
: Main Query + (Sub Query) : 메인 쿼리 내부에 쿼리를 하나 더 넣는 문법
1. 쿼리 안의 쿼리를 다루는 문법
2. join과 어느 정도 호환
3. 문법적으로 order by 는 차단되어 있다.
4. 중첩 서브쿼리도 가능하다.
5. where 뿐만이 아니라, 모든 곳에서 사용될 수 있다.
6. 반환 종류와 활용법에 따라 다양하게 나뉜다.
: 서브 쿼리의 반환값이 단일행일 때
-- 특정 직원의 매니저 이름을 알아내세요.
select * from employee where emp_name = '전지연';
select emp_name from employee where emp_id = 214;
select emp_name from employee
where emp_id= -- 메인 쿼리
(select manager_id from employee where emp_name='전지연'); -- 서브 쿼리
-- 딱 한 개의 값이 출력된다.
select e2.emp_name
from employee e1
join employee e2 on (e1.manager_id = e2.emp_id)
where
e1.emp_name='전지연';
-- 전 직원의 평균 급여보다 많은 급여를 받는 직원의 사번, 이름, 직급코드, 급여를 출력하세요
select emp_id, emp_name, job_code, salary
from employee
where
(select avg(salary) from employee)<=salary;
: 서브 쿼리의 결과가 여러 행을 반환할 때
=(같다)
비교를 사용할 수 없다.in, any, all
을 이용해 여러 값 중 하나를 고르게 한다.-- 송종기나, 박나라가 속한 부서의 직원 이름, 부서코드, 급여를 출력하시오
select dept_code from employee
where emp_name = '송종기';
select dept_code from employee
where emp_name = '박나라';
select emp_name, dept_code, salary from employee
where dept_code in ('D5', 'D9');
select
emp_name, dept_code, salary from employee
where
dept_code in
(select dept_code from employee where emp_name in ('송종기', '박나라'));
예) J3 직급인 사람들의 급여보다 더 큰 급여를 가진 직원의 이름과 급여를 출력
-- J3 직급인 사람들의 급여보다 더 큰 급여를 가진 직원의 이름과 급여를 출력
-- all : 다중행의 모든 결과 중 1개
select emp_name, salary
from employee
where salary > all (select salary from employee where job_code='J3');
-- any : 다중행의 모든 결과
select emp_name, salary
from employee
where salary > any (select salary from employee where job_code='J3');
: 반환 값이 여러 열인 서브 쿼리 또는 여러 열과 여러 행이 서브 쿼리
[ 문법 ]
(값 1, 값2) = (select 값1, 값2 from 테이블 where 조건);
(dept_code, job_code)
= (select dept_code, job_code from employee where ent_yn='Y)
: 다중 행-열 또는 단일행으로 받는 반환 값을 메인쿼리로 담을 때, 조건이 존재
전제 : 같은 컬럼 값은 컴퓨터가 구분할 수 없다.
=(같다)
는 다중행, 다중행열의 경우 적용할 수 없다.: 주로 select
절에 들어가는 서브쿼리
select
emp_name 직원명,
(select dept_title from department where dept_code = dept_id) 부서명
-- 조건을 걸어서 가져옴.
from employee;
위 예제는 서브쿼리가 상관 쿼리로 사용된 예시이다.
이를 통해 다음 특징을 알 수 있다.
[ 특징 ]
1. 외부 테이블에서 값을 끌어왔다.
2. 상관 쿼리는 메인 쿼리의 데이터를 사용힌다.
3. 실행 순서는 from 을 제외하고, 서브쿼리가 먼저 실행된다.
4. 메인 쿼리와 연관되어 동작하는 쿼리는 의미에서 상(호연)관 쿼리
5. 출력마다 한 번씩 서브쿼리를 동작하기 때문에 성능이 안 좋다.
6. 홀로 사용될 수 없다.
: from 절에서 주로 사용되는 서브쿼리
select * from employee;
select * from (select emp_name, salary from employee);
객체가 아닌 “데이터”를 넣을 때 사용
insert into <테이블명> values (입력값);
-- `into` `values()` 와 함께 사용된다.
-- 데이터를 각 컬럼별로 넣을 때는 다음과 같이 사용한다.
insert into <테이블명> (컬럼명) values (입력값);
데이터를 수정할 때 사용
update <테이블명> set (대상컬럼 = 수정값); -- 기본
insert into cafe values(1000, 'Americano', 3000, 'Y');
insert into cafe values(1001, 'CafeLatte', 4000, 'Y');
update cafe set price = 1500; -- 모든 가격이 바뀐다.
update cafe set price = 1500 where pid=1000; -- 조건을 걸어 사용
-- 여러 행을 동시에 수정할 때
update cafe set price = 2500, iced='N' where pid = 1000;
데이터를 지울 때 사용
delete from <테이블명> where 조건; -- 조건이 없으면 모든 행을 삭제한다.
Transaction Control Language
트랜잭션을 통제하는 명령어
: 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위
insert, delete, update
만 트랜잭션에 걸린다.[ 특징 ]
: 트랜잭션에 쌓인 명령이 DB에 모두 반영되던지, 아니면 모두 반영되지 말아야 한다.
작업의 원자성은 개발자에게 가장 중요하다.
하나의 작업에 연결된 각 쿼리에 의한 데이터가 입력, 삭제, 수정될 때,
모든 쿼리가 일관된 결과를 가져야 한다. 한 개의 쿼리라도 실행되지 않는다면
각 쿼리에 연결된 테이블의 데이터가 꼬일 수 있다.
이런 문제로부터 보호하기 위해 트랜잭션은 모든 쿼리가 성공해야 DB에 커밋을 한다.
: 트랜잭션의 처리 결과가 일관성이 있어야 한다.
트랜잭션 중 DB가 변경되어도, 실행하는 시점의 DB를 이용해야 한다.
이게 없으면 모든 DB사용자가 사용할 때마다 달라지는 DB를 봐야 한다.
: 둘 이상의 세션이 DB에 연결하게 되면, 먼저 진행 중인 트랜잭션이 끝날 때까지 실행되지 않는다.
동시에 다른 수정(생성, 수정, 삭제)작업을 진행하지 못하게 오라클에서 막아버린다.
만약 동시 같은 데이터를 누군 수정하고, 삭제할 수 있다면 해당 데이터는 안전하지 못하다.
: 트랜잭션이 성공했을 경우, 그 결과는 DB에 영구적으로 반영되어야 한다.
트랜잭션이 성공하여 쌓인 명령의 결과를 DB에 반영함
commit;
입력트랜잭션에 쌓인 명령을 취소한다.
delete
로 데이터를 날려도, 커밋을 하지 않는 이상 명령은 DB에 반영되지 않고 트랜잭션에 쌓여 있다.rollback;
을 하게 되면 해당 명령이 사라진다.롤백 시, 돌아갈 위치를 설정하
delete from employee where dept_code = ‘J3’;
savepoint point1; -- point1 기준점 생성
delete from employee where emp_name='선동일';
savepoint point2; -- point2 기준점 생성
rollback to point1 -- point1로 돌아감. (선동일은 삭제되지 않음)
rollback to point2 -- point2로 돌아감. (J3, 선동일이 삭제되어 있음)
commit
이 되는 순간, savepoint
를 이용할 수 없다. (트랜잭션이 종료됨)