무결성: 정확성과 일관성을 유지 및 보증하는 것
ALTER TABLE
문을 사용하여 다음을 수행
ALTER TABLE <table_name>
ADD [CONSTRAINT <constraint_name>]
type (<colun_name>);
ALTER TABLE emp2
MODIFY employee_id PRIMARY KEY;
📌 primary key를 참조하고 있는 foreign key가 있을 수 있기 때문에
제약조건을 연쇄화시켜서 같이 날려버릴 수 있도록 `CASCADE 써줘야 됨
ONLINE
키워드를 지정하여 제약조건을 삭제하는 동안
테이블에서의 DML 작업이 허용됨을 나타냄
상위 키가 삭제될 때 하위 행도 삭제하려면
ON DELETE CASCADE절 사용
ALTER TABLE dept2 ADD CONSTRAINT dept_lc_fk
FOREIGN KEY (location_id)
REFERENCES locations(location_id) ON DELETE CASCADE;
상위 키가 삭제될 때 하위 행 값을 null로 설정하려면
ON DELETE SET NULL절 사용
ALTER TABLE dept2 ADD CONSTRAINT emp_dt_fk
FOREIGN KEY (department_id)
REFERENCES locations(department_id) ON DELETE SET NULL;
DROP COLUMN
절과 함께 사용PRIMARY
및 UNIQUE
키를 참조하는 모든 참조 무결성 제약조건 삭제ALTER TABLE emp2
DROP COLUMN employee_id CASCADE CONSTARINTS;
예를 들어, employee_id가 pk(primary key)이고 이 pk 값을 참조하는 fk(foreign key)가 있다면, 컬럼을 먼저 삭제하는 것이 불가능할 때가 있음
--> CASCADE CONSTARINTS
를 사용해서 같이 연쇄화시켜 삭제하라는 의미
ALTER TABLE test1
DROP (col1_pk, col2_fk, col1);
테이블의 이름을 바꾸려면 ALTER TABLE
문의 RENAME TABLE
절 사용
ALTER TABLE marketing RENAME to new_marketing;
테이블 열의 이름을 바꾸려면 ALTER TABLE
문의 RENAME COLUMN
절 사용
ALTER TABLE new_marketing RENAME COLUMN team_id TO id;
테이블에 대한 기존 제약조건의 이름을 바꾸려면 ALTER TABLE
문의 RENAME CONSTRAINT
절 사용
ALTER TABLE new_marketing RENAME CONSTRAINT mktg_pk TO new_mktg_pk;
-- 나를 참조하고 있는 fk가 있어서 drop 안됨
ALTER TABLE copy_emp
DROP PRIMARY KEY;
-- 나를 참조하고 있던 fk 먼저 지우고
ALTER TABLE copy_emp
DROP CONSTRAINT cpemp_mgr_fk;
-- 그러고나서 pk 삭제하면 됨
ALTER TABLE copy_emp
DROP PRIMARY KEY;
-- pk제약조건을 삭제할 때
-- 나를 참조하고 있는 fk를 같이 연쇄화시켜 삭제가능
ALTER TABLE copy_emp
DROP PRIMARY KEY CASCADE;
-- copy_dept의 컬럼삭제
-- 참조되고있는 제약조건 있으면 오류남
ALTER TABLE copy_dept
DROP (department_id) ;
-- 문제가 되는 제약조건 먼저 연쇄화시켜 날려버림
ALTER TABLE copy_dept
DROP (department_id) CASCADE CONSTRAINTS ;
-- 테이블이름 변경
ALTER TABLE copy_dept RENAME TO cp_dept ;
-- 다시 되돌아옴
ALTER TABLE cp_dept RENAME TO copy_dept ;
-- 컬럼이름 변경
ALTER TABLE copy_dept RENAME COLUMN manager_id TO mgrid ;
ALTER TABLE
문의 DISABLE
절을 실행하여 무결성 제약조건을 비활성화 함
Primary key
를 비활성화하려면 CASCADE
옵션을 적용
--> 그러면 종속된 모든 foreign key
제약조건도 자동으로 비활성화
ALTER TABLE employees
DISABLE CONSTRAINT EMP_EMAIL_UK ;
다시 검색하겠다는 의미
ENABLE절을 사용하여 테이블 정의에서 현재 비활성화된 무결성 제약조건을 활성화 함
unique key 또는 primary key 제약조건을 활성화하면
--> unique 인덱스 자동 생성
ALTER TABLE employees
ENABLE CONSTRAINT EMP_EMAIL_UK ;
테이블에 정의된 무결성 제약조건의 상태는 다음 중 하나일 수 있음
- ENABLE VALIDATE (default값)
- ENABLE NOVALIDATE
- DISABLE VALIDATE
- DISABLE NOVALIDATE (default값)
disable
상태라면 --> 제약이 꺼져있으므로 insert 가능
VALIDATE
: 유효성 검증 하겠다NOVALIDATE
: 유효성 검증 안하겠다-- 오류발생: 0은 들어올 수 없는 값
UPDATE employees
SET salary = 0
WHERE employee_id = 101 ;
-- disable: 제약조건에 위배되는 값도 들어갈 수 있음
ALTER TABLE employees
DISABLE NOVALIDATE CONSTRAINT EMP_SALARY_MIN ;
-- 성공
UPDATE employees
SET salary = 0
WHERE employee_id = 101 ;
-- 오류발생: 잘못된 값(salary = 0)이 이미 들어가 있어서
-- 현재 삽입된 데이터가 제약조건 위배상태
ALTER TABLE employees
ENABLE VALIDATE CONSTRAINT EMP_SALARY_MIN ;
-- 신규 데이터 제약조건 활성 + novalidate(기존 데이터 유효성 검증 제외) 상태
-- Enable: 신규 데이터의 제약조건은 반영
-- Novalidate: 위배된 데이터는 유지
ALTER TABLE employees
ENABLE NOVALIDATE CONSTRAINT EMP_SALARY_MIN ;
-- 성공
SELECT employee_id, salary
FROM employees
WHERE employee_id = 101 ;
-- 오류발생: 신규 데이터는 제약조건 활성화(Enable) 상태이므로 삽입 불가
UPDATE employees
SET salary = 0
WHERE employee_id = 102 ;
Enable
: 신규 데이터의 제약조건은 반영Novalidate
: 위배된 데이터는 유지
DEFERRABLE
또는NOT DEFERRABLE
INITIALLY DEFERRED
또는INITIALLY IMMEDIATE
제약조건의 검증 시기를 지연시킬 수 있음
INITIALLY DEFERRED
: 트랜잭션이 종료될 때까지 제약조건 검사를 기다림INITIALLY IMMEDIATE
: 명령문 실행이 완료되면 제약조건을 검사함ALTER TABLE copy_emp
ADD PRIMARY KEY (employee_id) DEFERRABLE INITIALLY DEFERRED ENABLE VALIDATE;
SELECT *
FROM copy_emp ;
-- 중복값이 생기니까 원래는 에러 나야함
UPDATE copy_emp
SET employee_id = 100
WHERE employee_id = 101 ;
-- 100번이 2개 생김
SELECT *
FROM copy_emp ;
-- 오류발생 -> 롤백됨
COMMIT ;
-- 100번 행 하나 다시 101번으로 바뀜
SELECT *
FROM copy_emp ;
DROP TABLE ... PURGE
purge
: 임시로 저장하지 않고 완전 삭제 옵션
⭐ 두개 잘 구분해야 함
CREATE GLOBAL TEMPORARY TABLE cart(n NUMBER, d DATE)
ON COMMIT DELETE ROWS;
트랜잭션이 유지되는 동안에만 데이터가 살아있고
COMMIT이 들어가면 데이터가 싹 지워짐
CREATE GLOBAL TEMPORARY TABLE today_sales
ON COMMIT PRESERVE ROWS AS
SELECT * FROM orders
WHERE order_date = SYSDATE;
세션이 유지되는 동안에만 데이터가 살아있음
세션이 종료되면 테이블 데이터 삭제
CREATE GLOBAL TEMPORARY TABLE cart
(id NUMBER(2),
name VARCHAR2(10))
ON COMMIT DELETE ROWS;
-- insert됨
INSERT INTO cart VALUES (1, 'A') ;
-- 데이터 검색됨
SELECT * FROM cart ;
COMMIT ;
-- 데이터가 사라짐
SELECT * FROM cart ;
CREATE GLOBAL TEMPORARY TABLE cart2
(id NUMBER(2),
name VARCHAR2(10))
ON COMMIT PRESERVE ROWS;
INSERT INTO cart2 VALUES (1, 'A') ;
COMMIT ;
-- 데이터 안사라지고 그대로 있음
-- 접속 끊었다가 다시 들어오면 데이터 사라짐
SELECT * FROM cart2 ;
외부 데이터를 가져올 때
SYSTEM> CREATE OR REPLACE DIRECTORY emp_dir AS 'C:\DATA' ;
SYSTEM> GRANT read, write ON DIRECTORY emp_dir TO ORA1 ;
읽기 전용 테이블이기 때문에 DML(insert, update, delete)은 안됨
테이블이 만들어지면 해당 테이블의 정의사항은 DB 안에 있지만,
실제 데이터는 밖에 있음
--> 조회 작업을 통해 밖에 있는 것을 가져다가 보여줄 수 있음