2020년 12월 21일 9시 ~ 15시 30분 zoom으로 수업 진행
CHECK 제약조건
컬럼에 값을 기록할 때 지정한 값 이외에는 값이 기록되지 않도록 범위를 제한하는 조건
CHECK(컬럼명 비교연산자 값)
PRIMARY KEY 제약조건
'기본키 제약조건'
테이블 내에서 한 행 한 행을 식별하기 위한 고유의 값을 가지는 컬럼
NOT NULL, UNIQUE 제약 조건을 함께 걸어준다
테이블 전체에 각 데이터들간의 식별자 역할을 수행시키는 제약조건이다
FOREIGN KEY 제약조건
외래키, 외부키, 참조키
다른 테이블의 컬럼 값을 참조하여(REFERENCE)
참조하는 테이블의 값만 허용한다
해당 제약조건을 통해 다른 테이블과의 관계(RELATIONSHIP)가 형성된다.
컬럼레벨
REFERENCES 참조할테이블명[(참조할 컬럼명)] [삭제 옵션]
테이블 레벨
FOREIGN KEY(적용할 컬럼) REFERENCES [(참조할테이블명)] [삭제 옵션]
FOREIGN KEY 제약조건 : 참조할 컬럼 명이 생략 될 경우
참조 대상 테이블의 기본키를 참조 할 컬럼으로 가져온다.
참조하고자 하는 컬럼은 반드시 PRIMARY KEY 이거나 UNIQUE 제약조건이 걸려있어야 한다.
DML (데이터 조작 언어)
INSERT, UPDATE, DELETE, SELECT -> 통틀어서 CRUD라고 부른다.
[CRUD]
C(CREATE) : INSERT / 데이터 추가
R(READ) : SELECT / 데이터 조회
U(UPDATE) : UPDATE / 데이터 수정
D(DELETE) : DELETE / 데이터 삭제
INSERT
새로운 행을 특정 테이블에 추가하는 명령어
사용형식
1. 특정 컬럼에 값을 추가하는 방법
INSERT INTO 테이블명(컬럼명 , ...) VALUES(값1, 값2, ...);
2. 모든 컬럼에 값을 추가하는 방법
INSERT INTO 테이블명 VALUES(값1, 값2, ...);
--1221
--DAY 6
--UNIQUE 제약조건을 여러 컬럼에 적용하기
--D1 --200
--D1 --201
--D2 --200
--D2 --201
--예를들어, 이름 컬럼과 주민번호 컬럼이 있다면 , 한 컬럼에만 UNIQUE 가 걸려있을 땐
--김민지 + 940922~ 김민지 + 870708~ 은 같이 있을 수 없다. 하지만 여러컬럼에
-- UNIQUE를 걸게되면 둘다 중복되야 중복자료로 인정하고 오류가 뜬다
CREATE TABLE USER_UNIQUE3(
USER_NO NUMBER,
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(15),
UNIQUE(USER_NO,USER_ID)
);
INSERT INTO USER_UNIQUE3
VALUES(1,'USER01','PASS01','LEE');
INSERT INTO USER_UNIQUE3
VALUES(1,'USER02','PASS02','KIM');
INSERT INTO USER_UNIQUE3
VALUES(2,'USER01','PASS03','HONG');
INSERT INTO USER_UNIQUE3
VALUES(2,'USER02','PASS04','BEAK');
SELECT * FROM USER_UNIQUE3;
--제약조건에 이름 설정하기
CREATE TABLE CONS_NAME(
NO1 NUMBER CONSTRAINT NN_NO1 NOT NULL,
DATA1 VARCHAR2(20) CONSTRAINT UN_DATA UNIQUE,
DATA2 VARCHAR(20),
CONSTRAINT UK_DATA2 UNIQUE(DATA2)
);
--CONS_NAME테이블에서 선언한 제약조건들 전보 조회하는 코드
SELECT * FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'CONS_NAME';
--CHECK 제약조건
--컬럼에 값을 기록할 때 지정한 값 이외에는 값이 기록되지 않도록 범위를 제한하는 조건
--CHECK(컬럼명 비교연산자 값)
CREATE TABLE USER_CHECK(
NO NUMBER,
ID VARCHAR2(20),
PW VARCHAR2(30),
NAME VARCHAR2(15),
GENDER CHAR(3) CHECK (GENDER IN ('남','여'))
);
INSERT INTO USER_CHECK
VALUES(1,'USER01','PASS01','LEE','남'); --체크조건을 만족함
INSERT INTO USER_CHECK
VALUES(1,'USER01','PASS01','LEE','남자');--체크조건 불만족 오류
INSERT INTO USER_CHECK
VALUES(1,'USER01','PASS01','LEE','M');--체크조건 불만족 오류
INSERT INTO USER_CHECK
VALUES(2,'USER02','PASS02','BAE','여'); --체크조건을 만족함
SELECT * FROM USER_CHECK;
--CHECK 제약조건에 부등호로 표기
CREATE TABLE TEST_CHECK2(
TEST_DATA NUMBER,
CONSTRAINT CK_TEST_DATA CHECK(TEST_DATA >0)
);
INSERT INTO TEST_CHECK2 VALUES(10);
INSERT INTO TEST_CHECK2 VALUES(-10);
--넣는 데이터가 0보다 작아서 check 제약조건에 위배되어 오류난다.
--check constraint
SELECT * FROM TEST_CHECK2;
CREATE TABLE TEST_CHECK3(
CPRICE NUMBER,
CDATE DATE,
CONSTRAINT CK_TEST3_CPRICE CHECK(CPRICE BETWEEN 1 AND 999999),
CONSTRAINT CK_TEST3_CDATE CHECK(CDATE >= TO_DATE('2020/01/01', 'YYYY/MM/DD'))
);
--제약조건 여러 개 설정
CREATE TABLE TEST_DOUBLE_CONS (
TEST_NO NUMBER NOT NULL UNIQUE,
TEST_NO2 NUMBER NOT NULL
);
SELECT * FROM USER_CONS_COLUMNS
WHERE TABLE_NAME = 'TEST_DOUBLE_CONS';
--제약조건을 동시에 선언하는 것 뿐이지 제약조건의 이름이 같은 건 아님
--PRIMARY KEY 제약조건
--'기본키 제약조건'
--테이블 내에서 한 행 한 행을 식별하기 위한 고유의 값을 가지는 컬럼
--NOT NULL, UNIQUE 제약 조건을 함께 걸어준다
--테이블 전체에 각 데이터들간의 식별자 역할을 수행시키는 제약조건이다
--
CREATE TABLE USER_PK_TABLE(
USER_NO NUMBER CONSTRAINT PK_USER_NO PRIMARY KEY,
USER_ID VARCHAR2(20) UNIQUE,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2(15) NOT NULL,
GENDER CHAR(30) CHECK(GENDER IN('남', '여'))
);
SELECT * FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'USER_PK_TABLE';
INSERT INTO USER_PK_TABLE VALUES(1, 'USER01', 'PASS01','LEE', '남');
INSERT INTO USER_PK_TABLE VALUES(2, 'USER02', 'PASS02','KIM', '여');
INSERT INTO USER_PK_TABLE VALUES(1, 'USER03', 'PASS03','PARK', '남');
--unique constraint (TEST.PK_USER_NO) violated 에러난다.
INSERT INTO USER_PK_TABLE VALUES(NULL, 'USER03', 'PASS03','PARK', '남');
--cannot insert NULL into ("TEST"."USER_PK_TABLE"."USER_NO") 에러난다
--기본키 제약조건을 설정할 경우 자동으로 NOT NULL, UNIQUE 설정된다.
--기본키 제약조건을 여러 컬럼에 적용
CREATE TABLE USER_PK_TABLE2(
USER_NO NUMBER,
USER_ID VARCHAR2(20) UNIQUE,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2(15) NOT NULL,
GENDER CHAR(30) CHECK(GENDER IN('남', '여')),
--CONSTRAINT PK_USER_NO PRIMARY KEY 는 안됨 -> 다른 테이블에서 같은 이름을 가진 제약조건이 존재하기 떄문
CONSTRAINT PK_USER_NO2 PRIMARY KEY(USER_NO, USER_ID)
);
--1, 'USER01' ==> 성공
--2, 'USER02' ==> 성공
--1, 'USER03' ==> 성공 (왜 되냐구? PRIMARY KEY 제약조건을 USER_NO, USER_ID 두 개 묶어서 설정했기 때문에!!
-- 두 개 한번에 비교했을때가 기준이 됨! user_id 유니크 제약조건 위배x , user_no는 제약조건 건게 없어서 삽가능!
--2, 'USER02' ==> 실패 (USER_ID 를 UNIQUE로 설정해서 유니크 제약조건에 위배되니까 안되는 것)
--user_no, user_id 를 묶어서 기본키 제약 조건을 설정한것이다!
--DROP은 객체를 삭제한다.
DROP TABLE MEMBER;
--FOREIGN KEY 제약조건
--외래키, 외부키, 참조키
--다른 테이블의 컬럼 값을 참조하여(REFERENCE)
--참조하는 테이블의 값만 허용한다
--해당 제약조건을 통해 다른 테이블과의 관계(RELATIONSHIP)가 형성된다.
--컬럼레벨
--REFERENCES 참조할테이블명[(참조할 컬럼명)] [삭제 옵션]
--테이블 레벨
--FOREIGN KEY(적용할 컬럼) REFERENCES [(참조할테이블명)] [삭제 옵션]
--참조할 컬럼 명이 생략 될 경우
--참조 대상 테이블의 기본키를 참조 할 컬럼으로 가져온다.
--참조하고자 하는 컬럼은 반드시 PRIMARY KEY 이거나 UNIQUE 제약조건이 걸려있어야 한다.
DROP TABLE USER_GRADE;
CREATE TABLE USER_GRADE(
GRADE_CODE NUMBER PRIMARY KEY,
GRADE_NAME VARCHAR2(30) NOT NULL
);
INSERT INTO USER_GRADE VALUES(1, '일반회원');
INSERT INTO USER_GRADE VALUES(2, 'SILVER');
INSERT INTO USER_GRADE VALUES(3, 'GOLD');
INSERT INTO USER_GRADE VALUES(4, 'VIP');
INSERT INTO USER_GRADE VALUES(10, 'MANAGER');
SELECT * FROM USER_GRADE;
--
DROP TABLE USER_FOREIGN_KEY;
CREATE TABLE USER_FOREIGN_KEY(
USER_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(15),
GENDER CHAR(1) CHECK(GENDER IN('M', 'F')),
GRADE_CODE NUMBER,
FOREIGN KEY(GRADE_CODE) REFERENCES USER_GRADE(GRADE_CODE)
--USER_FOREIGN_KEY테이블의 GRADE_CODE컬럼에 FK_GRADE_CODE 라는 이름의 외래키 제약조건을 걸 것이다.
--이는 참조테이블 USER_GRADE의 GRADE_CODE컬럼을 참조할것으로 설정한다.
);
INSERT INTO USER_FOREIGN_KEY VALUES(1, '123', '321' , 'LEE', 'F', 2);
INSERT INTO USER_FOREIGN_KEY VALUES(2, 'ABC', 'CBA' , 'KIM', 'M', 4);
INSERT INTO USER_FOREIGN_KEY VALUES(3, '456', '654' , 'PARK', 'M', 1);
INSERT INTO USER_FOREIGN_KEY VALUES(4, 'DEF', 'FED' , 'CHO', 'F', 3);
INSERT INTO USER_FOREIGN_KEY VALUES(5, 'QWE', 'EWQ' , 'JANG', 'F', 1);
SELECT * FROM user_foreign_key;
INSERT INTO USER_FOREIGN_KEY VALUES(6, 'QWE', 'EWQ' , 'JANG', 'F', 10);
--integrity constraint (TEST.FK_GRADE_CODE) violated - parent key not found 에러난다.
--참조하는 테이블의 컬럼에 10이라는 값이 없어서 발생하는 에러
--INSERT INTO USER_GRADE VALUES(10, 'MANAGER'); 추가해주니 에러가 발생하지 않음
SELECT *
FROM user_foreign_key
JOIN USER_GRADE USING(GRADE_CODE);
--삭제 옵션
DELETE FROM USER_GRADE
WHERE GRADE_CODE = 10;
--에러난다 integrity constraint (TEST.FK_GRADE_CODE) violated - child record found
--참조하는 데이터? 테이블? 이 있을 경우 삭제하지 못 한다.
--참조되고(USER_GRADE) 있는 원본 테이블의 걸럼 값이 삭제될 때
--참조하고(USER_FOREIGN_KEY) 있는 값을 어떻게 처리할 것인지 설정하는 옵션
--일반적으로 원본 컬럼 내용을 삭제하고자 할 때 외래키로 사용중인 자식이 존재한다면 함부로 삭제할 수 없다.
--1. 부모 컬럼을 삭제할 때 자식을 NULL 로 변경하기
--ON DELETE SET NULL
--2. 부모 컬럼을 삭제할 때 관련된 자식도 함께 삭제하기
--ON DELETE CASCADE
--
DROP TABLE USER_GRADE;
--unique/primary keys in table referenced by foreign keys 에러
--USER_FOREIGN_KEY을 먼저 지우고, USER_GRADE을 지우면 된다 -> 참조되는 테이블이 없기때문에
DROP TABLE USER_FOREIGN_KEY;
DROP TABLE USER_GRADE;
CREATE TABLE USER_GRADE(
GRADE_CODE NUMBER PRIMARY KEY,
GRADE_NAME VARCHAR2(30) NOT NULL
);
INSERT INTO USER_GRADE VALUES(1, '일반회원');
INSERT INTO USER_GRADE VALUES(2, 'SILVER');
INSERT INTO USER_GRADE VALUES(3, 'GOLD');
INSERT INTO USER_GRADE VALUES(4, 'VIP');
INSERT INTO USER_GRADE VALUES(10, 'MANAGER');
SELECT * FROM USER_GRADE;
--1. USER_FOREIGN_KEY + ON DELETE SET NULL
CREATE TABLE USER_FOREIGN_KEY(
USER_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(15),
GENDER CHAR(1) CHECK(GENDER IN('M', 'F')),
GRADE_CODE NUMBER,
FOREIGN KEY(GRADE_CODE)
REFERENCES USER_GRADE(GRADE_CODE) ON DELETE SET NULL
);
INSERT INTO USER_FOREIGN_KEY VALUES(1, '123', '321' , 'LEE', 'F', 2);
INSERT INTO USER_FOREIGN_KEY VALUES(2, 'ABC', 'CBA' , 'KIM', 'M', 4);
INSERT INTO USER_FOREIGN_KEY VALUES(3, '456', '654' , 'PARK', 'M', 1);
INSERT INTO USER_FOREIGN_KEY VALUES(4, 'DEF', 'FED' , 'CHO', 'F', 3);
INSERT INTO USER_FOREIGN_KEY VALUES(5, 'QWE', 'EWQ' , 'JANG', 'F', 1);
SELECT * FROM USER_FOREIGN_KEY;
COMMIT;
--지우기 전에 데이터베이스 내용 저장
--커밋 시점까지만 데이터가 저장됨
DELETE FROM USER_GRADE
WHERE GRADE_CODE = 4;
--삭제 된다.
SELECT * FROM USER_GRADE;
--진짜 삭제됐다.
SELECT * FROM USER_FOREIGN_KEY;
--데이터가 삭제될 경우, 해당 데이터를 참조하고 있던 자식의 값을 NULL 값으로 바꿔버린다.
--2. USER_FOREIGN_KEY + ON DELETE CASCADE
DROP TABLE USER_FOREIGN_KEY;
CREATE TABLE USER_FOREIGN_KEY(
USER_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(15),
GENDER CHAR(1) CHECK(GENDER IN('M', 'F')),
GRADE_CODE NUMBER,
FOREIGN KEY(GRADE_CODE)
REFERENCES USER_GRADE(GRADE_CODE) ON DELETE CASCADE
);
INSERT INTO USER_FOREIGN_KEY VALUES(1, '123', '321' , 'LEE', 'F', 2);
INSERT INTO USER_FOREIGN_KEY VALUES(2, 'ABC', 'CBA' , 'KIM', 'M', 4);
INSERT INTO USER_FOREIGN_KEY VALUES(3, '456', '654' , 'PARK', 'M', 1);
INSERT INTO USER_FOREIGN_KEY VALUES(4, 'DEF', 'FED' , 'CHO', 'F', 3);
INSERT INTO USER_FOREIGN_KEY VALUES(5, 'QWE', 'EWQ' , 'JANG', 'F', 1);
SELECT * FROM USER_GRADE;
SELECT * FROM USER_FOREIGN_KEY;
DELETE FROM USER_GRADE
WHERE GRADE_CODE = 2;
--행 전체가 삭제되었다.
--부모가 삭제되면 그걸 참조하고있던 자식 데이터 자체가 삭제된다.
---------------------------------------------
SELECT * FROM EMPLOYEE;
--SUBQUERY 활용한 테이블 만들기
--SUBQUERY 사용하여 테이블을 생성할 경우
--컬럼명, 데이터 타입, 값, NOT NULL 은 복사 가능
--하지만 다른 제약조건은 복사되지 않는다!
CREATE TABLE EMPLOYEE_COPY
AS SELECT * FROM EMPLOYEE;
CREATE TABLE EMPLOYEE_COPY2
AS SELECT EMP_ID, EMP_NAME FROM EMPLOYEE;
--서브쿼리를 이용한 테이블 생성 시 , 셀렉트문의 결과를 바탕으로 테이블을 만드는 것이라 EMP_ID, EMP_NAME만 SELECT 시키고 테이블을 복사하면
--복사되는 테이블의 컬럼은 EMP_ID, EMP_NAME만 복사된다.
--원본 테이블
SELECT * FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'EMPLOYEE';
--서브쿼리를 이용한 테이블 복사
SELECT * FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'EMPLOYEE_COPY';
--USER_NAME 에 걸려있던 기본키 제약조건이 복사되지 않은 모습을 볼 수 있다.
SELECT * FROM EMPLOYEE_COPY;
--값도 잘 복사되어 있다.
SELECT * FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'EMPLOYEE_COPY2';
--테이블의 형식만 복사하기
--저장된 값 제외
DROP TABLE EMPLOYEE_COPY2;
CREATE TABLE EMPLOYEE_COPY2
AS SELECT * FROM EMPLOYEE WHERE 1=2;
--WHERE의 조건이 FALSE 인 상태로 서브쿼리가 실행되는 것이라 형식, 타입은 그대로 가져오나
--값이 없는 상태로 테이블이 복사.생성 된다.
SELECT * FROM EMPLOYEE_COPY2;
--값은 없으나 형식은 그대로 유지되어있는 모습 확인
SELECT * FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'EMPLOYEE_COPY2';
--제약조건도 잘 복사되어 있다.
--기본 값 설정하기
CREATE TABLE DEFAULT_TABLE(
COL1 VARCHAR2(30) DEFAULT '없음',
COL2 DATE DEFAULT SYSDATE
);
INSERT INTO DEFAULT_TABLE
VALUES(DEFAULT, DEFAULT);
SELECT * FROM DEFAULT_TABLE;
--DEFAULT 값대로 데이터가 저장되어 있는 모습을 확인 할 수 있다.
--제약조건을 테이블 생성 후 추가하는 DDL
-- [ALTER]
--ALTER TABLE 테이블명 ADD 제약조건~ : PRIMARY KEY . FOREIGN KEY, UNIQUE, CHECK
--ALTER TABLE 테이블명 MODIFY 컬럼명 NOT NULL -> NOT NULL은 이렇게 사용해야 한다.
--NOT NULL은 컬럼 레벨 제약조건으로만 설정할 수 있음을 알고 지나가자.
ALTER TABLE EMPLOYEE ADD FOREIGN KEY(DEPT_CODE) REFERENCES DEPARTMENT;
ALTER TABLE EMPLOYEE ADD FOREIGN KEY(SAL_LEVEL) REFERENCES SAL_GRADE;
ALTER TABLE EMPLOYEE ADD CHECK(ENT_YN IN ('Y', 'N'));
ALTER TABLE EMPLOYEE ADD UNIQUE(EMP_NO);
ALTER TABLE DEPARTMENT ADD FOREIGN KEY(LOCATION_ID) REFERENCES LOCATION;
-------------------------------------------------------------------------------------
--DML (데이터 조작 언어)
--INSERT, UPDATE, DELETE, SELECT -> 통틀어서 CRUD라고 부른다.
--[CRUD]
--C(CREATE) : INSERT / 데이터 추가
--R(READ) : SELECT / 데이터 조회
--U(UPDATE) : UPDATE / 데이터 수정
--D(DELETE) : DELETE / 데이터 삭제
--INSERT : 새로운 행을 특정 테이블에 추가하는 명령어
--사용형식
--1. 특정 컬럼에 값을 추가하는 방법
--INSERT INTO 테이블명(컬럼명 , ...) VALUES(값1, 값2, ...);
--2. 모든 컬럼에 값을 추가하는 방법
--INSERT INTO 테이블명 VALUES(값1, 값2, ...);
DESC EMPLOYEE;
--컬럼명을 명시하여 데이터 추가
INSERT INTO EMPLOYEE(EMP_ID, EMP_NAME, EMP_NO, EMAIL, PHONE, DEPT_CODE, JOB_CODE, SAL_LEVEL, SALARY, BONUS, MANAGER_ID, HIRE_DATE, ENT_DATE, ENT_YN)
VALUES(500, '이소근', '700101-1234567', 'leesg@naver.com', '01011112222', 'D1', 'J7', 'S4', 3100000, 0.1, '200', SYSDATE, NULL, DEFAULT);
SELECT * FROM EMPLOYEE WHERE EMP_ID = 500;
--컬럼을 생략하고 사용하기
INSERT INTO EMPLOYEE VALUES(900, '밥보검', '510101-1234567', 'bob_bg@naver.com', '01022223344', 'D1', 'J7', 'S3', 4300000, 0.2, '200', SYSDATE, NULL, DEFAULT);
--확인하기
SELECT * FROM EMPLOYEE WHERE EMP_ID = 900;
COMMIT;
--INSERT + SUBQUERY
CREATE TABLE EMP_01(
EMP_ID NUMBER,
EMP_NAME VARCHAR2(20),
DEPT_TITLE VARCHAR2(40)
);
INSERT INTO EMP_01(SELECT EMP_ID, EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
);
SELECT * FROM EMP_01;
'기록 > 자바_국비' 카테고리의 다른 글
[배운내용정리] 1223 자바 국비교육 _ Oracle (0) | 2021.01.09 |
---|---|
[배운내용정리] 1222 자바 국비교육 _ Oracle (0) | 2021.01.09 |
[배운내용정리] 1218 자바 국비교육 _ Oracle (0) | 2020.12.28 |
[배운내용정리] 1216 자바 국비교육 _ Oracle (0) | 2020.12.26 |
[배운내용정리] 1215 자바 국비교육 _ Oracle (0) | 2020.12.26 |