상세 컨텐츠

본문 제목

Oracle - PRIMARY KEY 설정 실습

IT/DBMS

by TMI1 2025. 7. 9. 12:49

본문

-- ■■■ PRIMARY KEY ■■■--

-- 1. 테이블에 대한 기본 키를 생성한다.

-- 2. 테이블에서 각 행을 유일하게 식별하는 컬럼(단일) 또는 컬럼의 집합(복합)이다.
--    기본 키는 테이블 당 최대 하나만 존재한다.
--    그러나 반드시 하나의 컬럼만으로만 구성되는 것은 아니다.
--    NULL 일 수 없고, 이미 테이블에 존재하고 있는 데이터를
--    다시 입력하거나 수정할 수 없도록 처리된다.
--    UNIQUE INDEX 가 자동으로 생성된다.
--    EX) 책의 부록 뒤에있는 찾기 = 인덱스 >> 빠른 검색을 위함 
--    (오라클이 자체적으로 만든다.)

-- 3. 형식 및 구조
-- 1) 컬럼 레벨의 형식
--    컬럼명 데이터 타입[CONSTRAINT CONSTRAINT명 PRIMARY KEY(컬럼명[, ...])]

--  2) 테이블 레벨의 형식 
--     문법적인 풀택스트를 이해하고 당분간 이걸 먼저 써라.. 
--     컬럼명 데이터타입,
--     컬럼명 데이터타입,
--     CONSTRAINT CONSTRAINT명 PRIMARY KEY(컬럼명[, ...])

--  4. CONSTRAINT 추가시 CONSTRAINT 명을 생략하면
--     오라클 서버가 자동적으로 CONSTRAINT 명을 부여하게 된다.
--     일반적으로 CONSTRAINT 명은 『테이블명_컬럼명_CONSTRAINT약어』
--     형식으로 기술한다.

--○ PK 지정 실습(① 컬럼 레벨의 형식)
-- 테이블 생성
CREATE TABLE TBL_TEST1
(   COL1 NUMBER(5)  PRIMARY KEY
,   COL2 VARCHAR2(30)
);
--==>> 테이블 생성

-- 데이터 입력
INSERT INTO TBL_TEST1(COL1, COL2) VALUES(1, 'TEST');
INSERT INTO TBL_TEST1(COL1, COL2) VALUES(2, 'ABCD');
INSERT INTO TBL_TEST1(COL1, COL2) VALUES(3, NULL); -- 아래줄과 같은 거
INSERT INTO TBL_TEST1(COL1) VALUES(4);
INSERT INTO TBL_TEST1(COL1, COL2) VALUES(2, 'ABCD');    --> 에러 발생 PRIMARY KEY
INSERT INTO TBL_TEST1(COL1, COL2) VALUES(2, 'KKKK');    --> 에러 발생
INSERT INTO TBL_TEST1(COL1, COL2) VALUES(5, 'ABCD');
INSERT INTO TBL_TEST1(COL1, COL2) VALUES(NULL, NULL);   --> 에러 발생 PK는 NOTNULL이므로 오류
INSERT INTO TBL_TEST1(COL1, COL2) VALUES(NULL, 'STUDY');--> 에러 발생
INSERT INTO TBL_TEST1(COL2) VALUES('STUDY');            --> 에러 발생

COMMIT;
--==>> 커밋 완료.

SELECT *
FROM TBL_TEST1;
--==>>
/*
1	TEST
2	ABCD
3	(null)
4	(null)
5	ABCD
*/

DESC TBL_TEST1;
--==>>
/*
이름   널?       유형           
---- -------- ------------ 
COL1 NOT NULL NUMBER(5)    → PK 제약 확인 불가 
COL2          VARCHAR2(30) 
*/
-- DESC 로는 PK는 확인 불가

--○ 제약조건 확인
SELECT *
FROM USER_CONSTRAINTS;
-- 데이터 딕셔너리 뷰 
/*
HR	REGION_ID_NN	C	REGIONS	"REGION_ID" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	REG_ID_PK	P	REGIONS					ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29	HR	REG_ID_PK		
HR	COUNTRY_ID_NN	C	COUNTRIES	"COUNTRY_ID" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	COUNTRY_C_ID_PK	P	COUNTRIES					ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29	HR	COUNTRY_C_ID_PK		
HR	COUNTR_REG_FK	R	COUNTRIES		HR	REG_ID_PK	NO ACTION	ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	LOC_CITY_NN	C	LOCATIONS	"CITY" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	LOC_ID_PK	P	LOCATIONS					ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29	HR	LOC_ID_PK		
HR	LOC_C_ID_FK	R	LOCATIONS		HR	COUNTRY_C_ID_PK	NO ACTION	ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	DEPT_NAME_NN	C	DEPARTMENTS	"DEPARTMENT_NAME" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	DEPT_ID_PK	P	DEPARTMENTS					ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29	HR	DEPT_ID_PK		
HR	DEPT_LOC_FK	R	DEPARTMENTS		HR	LOC_ID_PK	NO ACTION	ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	JOB_TITLE_NN	C	JOBS	"JOB_TITLE" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	JOB_ID_PK	P	JOBS					ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29	HR	JOB_ID_PK		
HR	EMP_LAST_NAME_NN	C	EMPLOYEES	"LAST_NAME" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	EMP_EMAIL_NN	C	EMPLOYEES	"EMAIL" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	EMP_HIRE_DATE_NN	C	EMPLOYEES	"HIRE_DATE" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	EMP_JOB_NN	C	EMPLOYEES	"JOB_ID" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	EMP_SALARY_MIN	C	EMPLOYEES	salary > 0				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	EMP_EMAIL_UK	U	EMPLOYEES					ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29	HR	EMP_EMAIL_UK		
HR	EMP_EMP_ID_PK	P	EMPLOYEES					ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29	HR	EMP_EMP_ID_PK		
HR	EMP_DEPT_FK	R	EMPLOYEES		HR	DEPT_ID_PK	NO ACTION	ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	EMP_JOB_FK	R	EMPLOYEES		HR	JOB_ID_PK	NO ACTION	ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	EMP_MANAGER_FK	R	EMPLOYEES		HR	EMP_EMP_ID_PK	NO ACTION	ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	DEPT_MGR_FK	R	DEPARTMENTS		HR	EMP_EMP_ID_PK	NO ACTION	ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	JHIST_EMPLOYEE_NN	C	JOB_HISTORY	"EMPLOYEE_ID" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	JHIST_START_DATE_NN	C	JOB_HISTORY	"START_DATE" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	JHIST_END_DATE_NN	C	JOB_HISTORY	"END_DATE" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	JHIST_JOB_NN	C	JOB_HISTORY	"JOB_ID" IS NOT NULL				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	JHIST_DATE_INTERVAL	C	JOB_HISTORY	end_date > start_date				ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	JHIST_EMP_ID_ST_DATE_PK	P	JOB_HISTORY					ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29	HR	JHIST_EMP_ID_ST_DATE_PK		
HR	JHIST_JOB_FK	R	JOB_HISTORY		HR	JOB_ID_PK	NO ACTION	ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	JHIST_EMP_FK	R	JOB_HISTORY		HR	EMP_EMP_ID_PK	NO ACTION	ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	JHIST_DEPT_FK	R	JOB_HISTORY		HR	DEPT_ID_PK	NO ACTION	ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			2014-05-29				
HR	SYS_C004102	O	EMP_DETAILS_VIEW					ENABLED	NOT DEFERRABLE	IMMEDIATE	NOT VALIDATED	GENERATED NAME			2014-05-29				
HR	SYS_C007013	P	TBL_TEST1					ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	GENERATED NAME			2025-07-09	HR	SYS_C007013		
*/

SELECT *
FROM USER_CONSTRAINTS
WHERE TABLE_NAME='TBL_TEST1';
--==>>
/*
HR	SYS_C007013	    P	TBL_TEST1					ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	GENERATED NAME			2025-07-09	HR	SYS_C007013		
    제약조건이름  타입   테이블명
*/

--○ 제약조건이 지정된 컬럼 확인(조회)
SELECT * 
FROM USER_CONS_COLUMNS;
--==>>
/*
HR	REGION_ID_NN	REGIONS	REGION_ID	
HR	REG_ID_PK	REGIONS	REGION_ID	1
HR	COUNTRY_ID_NN	COUNTRIES	COUNTRY_ID	
HR	COUNTRY_C_ID_PK	COUNTRIES	COUNTRY_ID	1
HR	COUNTR_REG_FK	COUNTRIES	REGION_ID	1
HR	LOC_ID_PK	LOCATIONS	LOCATION_ID	1
HR	LOC_CITY_NN	LOCATIONS	CITY	
HR	LOC_C_ID_FK	LOCATIONS	COUNTRY_ID	1
HR	DEPT_ID_PK	DEPARTMENTS	DEPARTMENT_ID	1
HR	DEPT_NAME_NN	DEPARTMENTS	DEPARTMENT_NAME	
HR	DEPT_MGR_FK	DEPARTMENTS	MANAGER_ID	1
HR	DEPT_LOC_FK	DEPARTMENTS	LOCATION_ID	1
HR	JOB_ID_PK	JOBS	JOB_ID	1
HR	JOB_TITLE_NN	JOBS	JOB_TITLE	
HR	EMP_EMP_ID_PK	EMPLOYEES	EMPLOYEE_ID	1
HR	EMP_LAST_NAME_NN	EMPLOYEES	LAST_NAME	
HR	EMP_EMAIL_NN	EMPLOYEES	EMAIL	
HR	EMP_EMAIL_UK	EMPLOYEES	EMAIL	1
HR	EMP_HIRE_DATE_NN	EMPLOYEES	HIRE_DATE	
HR	EMP_JOB_NN	EMPLOYEES	JOB_ID	
HR	EMP_JOB_FK	EMPLOYEES	JOB_ID	1
HR	EMP_SALARY_MIN	EMPLOYEES	SALARY	
HR	EMP_MANAGER_FK	EMPLOYEES	MANAGER_ID	1
HR	EMP_DEPT_FK	EMPLOYEES	DEPARTMENT_ID	1
HR	JHIST_EMPLOYEE_NN	JOB_HISTORY	EMPLOYEE_ID	
HR	JHIST_EMP_ID_ST_DATE_PK	JOB_HISTORY	EMPLOYEE_ID	1
HR	JHIST_EMP_FK	JOB_HISTORY	EMPLOYEE_ID	1
HR	JHIST_START_DATE_NN	JOB_HISTORY	START_DATE	
HR	JHIST_DATE_INTERVAL	JOB_HISTORY	START_DATE	
HR	JHIST_EMP_ID_ST_DATE_PK	JOB_HISTORY	START_DATE	2
HR	JHIST_END_DATE_NN	JOB_HISTORY	END_DATE	
HR	JHIST_DATE_INTERVAL	JOB_HISTORY	END_DATE	
HR	JHIST_JOB_NN	JOB_HISTORY	JOB_ID	
HR	JHIST_JOB_FK	JOB_HISTORY	JOB_ID	1
HR	JHIST_DEPT_FK	JOB_HISTORY	DEPARTMENT_ID	1
HR	SYS_C007013	TBL_TEST1	COL1	1
*/

SELECT * 
FROM USER_CONS_COLUMNS
WHERE TABLE_NAME='TBL_TEST1'; 
--==>>
/*
HR	SYS_C007013	TBL_TEST1	COL1	1
*/

--○ 제약조건이 설정된 소유주, 제약명, 테이블명, 제약종류, 컬럼명 항목 조회 
SELECT 소유주, 제약명, 테이블명, 제약종류, 컬럼명
FROM USER_CONSTRANITS UC, USER_CONS_COLUMNS UCC 
WHERE UC.CONSTRAINT_NAME = UCC.USER_CONSTRANITS.NAME;

SELECT UC.OWNER, UC.CONSTRAINT_NAME, UC.TABLE_NAME 
    ,UC.CONSTRAINT_TYPE, UCC.COLUMN_NAME 
FROM USER_CONSTRAINTS UC, USER_CONS_COLUMNS UCC
WHERE UC.CONSTRAINT_NAME = UCC.CONSTRAINT_NAME;

SELECT UC.OWNER, UC.CONSTRAINT_NAME, UC.TABLE_NAME 
    ,UC.CONSTRAINT_TYPE, UCC.COLUMN_NAME 
FROM USER_CONSTRAINTS UC, USER_CONS_COLUMNS UCC
WHERE UC.CONSTRAINT_NAME = UCC.CONSTRAINT_NAME
  AND UC.TABLE_NAME = 'TBL_TEST1';
--==>>
/*
HR	SYS_C007013	TBL_TEST1	COL1	1
*/

--○ PK 지정 실습(② 테이블 레벨의 형식)
-- 테이블 생성
CREATE TABLE TBL_TEST2
(   COL1 NUMBER(5)  
,   COL2 VARCHAR2(30)
,   CONSTRAINT TEST_COL1_PK PRIMARY KEY(COL1)
);
--==>> Table TBL_TEST2이(가) 생성되었습니다.
INSERT INTO TBL_TEST2(COL1, COL2) VALUES(1, 'TEST');
INSERT INTO TBL_TEST2(COL1, COL2) VALUES(2, 'ABCD');
INSERT INTO TBL_TEST2(COL1, COL2) VALUES(3, NULL);
INSERT INTO TBL_TEST2(COL1) VALUES(4);
INSERT INTO TBL_TEST2(COL1, COL2) VALUES(2, 'ABCD');    --> 에러발생
INSERT INTO TBL_TEST2(COL1, COL2) VALUES(2, 'TTTT');    --> 에러발생
INSERT INTO TBL_TEST2(COL1, COL2) VALUES(5, 'ABCD');
INSERT INTO TBL_TEST2(COL1, COL2) VALUES(5, NULL);      --> 에러발생
INSERT INTO TBL_TEST2(COL1, COL2) VALUES(NULL, 'STUDY'); --> 에러발생
INSERT INTO TBL_TEST2(COL2) VALUES('STUDY');--> 에러발생

COMMIT;
-->> 커밋완료

SELECT *
FROM  TBL_TEST2;
--==>>
/*
1	TEST
2	ABCD
3	(null)
4	(null)	
5	ABCD
*/

--○ 제약조건이 설정된 소유주, 제약명, 테이블명, 제약종류, 컬럼명 항목 조회 
--○ USER_CONSTRAINTS 와 USER_CONS_COLUMNS 를 대상으로
--   제약조건이 설정된 내용에 대해서
--   소유주, 제약조건명, 테이블명, 제약조건종류, 컬럼명 항목을 조회한다.

SELECT UC.OWNER "소유주", UC.CONSTRAINT_NAME, UC.TABLE_NAME 
    ,UC.CONSTRAINT_TYPE, UCC.COLUMN_NAME 
FROM USER_CONSTRAINTS UC, USER_CONS_COLUMNS UCC
WHERE UC.CONSTRAINT_NAME = UCC.CONSTRAINT_NAME
  AND UC.TABLE_NAME = 'TBL_TEST2';
--==>>
/*
HR	TEST_COL1_PK	TBL_TEST2	P	COL1
*/

--○ PK 지정 실습(③ 다중 컬럼 PK 지정 → 복합 프라이머리 키)
-- 테이블 생성
CREATE TABLE TBL_TEST3
(   COL1 NUMBER(5)  
,   COL2 VARCHAR2(30)
,   CONSTRAINT TEST3_COL1_COL2_PK PRIMARY KEY(COL1, COL2)
);
--==>> Table TBL_TEST3이(가) 생성되었습니다.

--(X) CHECK~!!! 
/*
CREATE TABLE TBL_TEST3
(   COL1 NUMBER(5)  
,   COL2 VARCHAR2(30)
,   CONSTRAINT TEST3_COL1_COL2_PK PRIMARY KEY(COL1)
    CONSTRAINT TEST3_COL1_COL2_PK PRIMARY KEY(COL2)
);
*/
INSERT INTO TBL_TEST3(COL1, COL2) VALUES(1, 'TEST');
INSERT INTO TBL_TEST3(COL1, COL2) VALUES(2, 'ABCD');
INSERT INTO TBL_TEST3(COL1, COL2) VALUES(3, NULL);      --> 에러발생
INSERT INTO TBL_TEST3(COL1) VALUES(4);                  --> 에러발생
INSERT INTO TBL_TEST3(COL1, COL2) VALUES(2, 'ABCD');    --> 에러발생 2번째에서 입력한 데이터임
INSERT INTO TBL_TEST3(COL1, COL2) VALUES(3, 'ABCD');
INSERT INTO TBL_TEST3(COL1, COL2) VALUES(1, 'ABCD');
INSERT INTO TBL_TEST3(COL1, COL2) VALUES(2, 'KKKK');    -- 2번만 겹친거지 뒤에게 다르니까 데이터들어감 
INSERT INTO TBL_TEST3(COL1, COL2) VALUES(4, 'ABCD'); 
INSERT INTO TBL_TEST3(COL1, COL2) VALUES(NULL, NULL);    --> 에러발생
INSERT INTO TBL_TEST3(COL1, COL2) VALUES(NULL, 'STUDY'); --> 에러발생
INSERT INTO TBL_TEST3(COL2) VALUES('STUDY');             --> 에러발생

COMMIT;

SELECT *
FROM TBL_TEST3;
--==>>
/*
1	ABCD
1	TEST
2	ABCD
2	KKKK
3	ABCD
4	ABCD
*/

--○ PK 지정 실습(④ 테이블 생성 이후 제약조건 추가 → PK지정)
-- 테이블 생성
CREATE TABLE TBL_TEST4
(   COL1 NUMBER(5)  
,   COL2 VARCHAR2(30)
);
--==>> Table TBL_TEST4이(가) 생성되었습니다.

--※ 이미 만들어져 있는 테이블에
--   부여하려는 제약조건을 위반한 데이터가 포함되어 있을 경우
--   해당 테이블에 제약조건을 추가하는 것은 불가능하다. 
-- EX) 1 '홍길동' 1 '고길동'  -- 이미 위반한 것에 제약조건 추가불가

-- 제약조건 추가
ALTER TABLE TBL_TEST4 
ADD CONSTRAINT TEST4_COL1_PK PRIMARY KEY(COL1);
-- Table TBL_TEST4이(가) 변경되었습니다.


SELECT UC.OWNER "소유주", UC.CONSTRAINT_NAME, UC.TABLE_NAME 
    ,UC.CONSTRAINT_TYPE, UCC.COLUMN_NAME 
FROM USER_CONSTRAINTS UC, USER_CONS_COLUMNS UCC
WHERE UC.CONSTRAINT_NAME = UCC.CONSTRAINT_NAME
  AND UC.TABLE_NAME = 'TBL_TEST2';

--※ 제약조건 확인 전용 뷰(VIEW) 생성 99코드
-- 뷰명 : VIEW_CONSTCHECK
CREATE OR REPLACE VIEW VIEW_CONSTCHECK
AS
SELECT UC.OWNER "OWNER"
    , UC.CONSTRAINT_NAME "CONSTRAINT_NAME"
    , UC.TABLE_NAME "TABLE_NAME"
    , UC.CONSTRAINT_TYPE "CONSTRAINT_TYPE"
    , UCC.COLUMN_NAME "COLUMN_NAME"
    , UC.SEARCH_CONDITION "SEARCH_CONDITION"
    , UC.DELETE_RULE "DELETE_RULE"
FROM USER_CONSTRAINTS UC JOIN USER_CONS_COLUMNS UCC 
ON UC.CONSTRAINT_NAME = UCC.CONSTRAINT_NAME; -- 이름이 같은걸로 결합하겠다.
--==>>View VIEW_CONSTCHECK이(가) 생성되었습니다.

--○ 생성된 뷰를 통한 제약조건 확인
SELECT *
FROM VIEW_CONSTCHECK
WHERE TABLE_NAME = 'TBL_TEST4';
--==>>
/*
HR	TEST4_COL1_PK	TBL_TEST4	P	COL1		
*/

-- ■■■UNIQUE(UK:U) ■■■--

-- 1. 테이블에서 지정한 컬럼의 데이터가 중복되지 않고
--    테이블 내에서 유일할 수 있도록 설정하는 제약조건.
--    PRIMARY KEY 와 유사한 제약조건이지만, NULL 을 허용한다는 차이가 있다.
--    내부적으로 PRIMARY KEY 와 마찬가지로 UNIQUE INDEX 가 자동 생성된다.
--    하나의 테이블 내에서 UNIQUE 제약조건은 여러 번 설정하는 것이 가능하다.
--    즉, 하나의 테이블에 UNIQUE 제약조건을 여러 개 만드는 것이 가능하다.

-- 2. 형식 및 구조
-- 1) 컬럼 레벨의 형식
-- 컬럼명 데이터타입[CONSTRAINT CONSTRAINT명] UNIQUE

-- 2) 테이블 레벨의 형식
-- 컬럼명 데이터타입,
-- 컬럼명 데이터타입,
-- CONSTRAINT CONSTRAINT명] UNIQUE(컬럼명[, ...]) 

--○ UK 지정 실습(① 컬럼 레벨의 형식)
-- 테이블 생성
CREATE TABLE TBL_TEST5
(   COL1 NUMBER(5)      PRIMARY KEY
,   COL2 VARCHAR2(30)   UNIQUE
);
--==>>Table TBL_TEST5이(가) 생성되었습니다.

--제약조건 조회
SELECT *
FROM VIEW_CONSTCHECK
WHERE TABLE_NAME='TBL_TEST5';
--==>>
/*
HR	SYS_C007017	TBL_TEST5	P	COL1
HR	SYS_C007018	TBL_TEST5	U	COL2
*/
--데이터 입력 
INSERT INTO TBL_TEST5(COL1, COL2) VALUES(1, 'TEST');
INSERT INTO TBL_TEST5(COL1, COL2) VALUES(2, 'ABCD');
INSERT INTO TBL_TEST5(COL1, COL2) VALUES(3, NULL);
INSERT INTO TBL_TEST5(COL1) VALUES(4); 
INSERT INTO TBL_TEST5(COL1, COL2) VALUES(5, 'ABCD');    --> 에러발생
INSERT INTO TBL_TEST5(COL1, COL2) VALUES(5, NULL);

COMMIT;

SELECT * 
FROM TBL_TEST5;
--==>>
/*
1	TEST
2	ABCD
3	(null)
4	(null)		
5	(null)	
*/

--○ UK 지정 실습(② 컬럼 레벨의 형식)
-- 테이블 생성
CREATE TABLE TBL_TEST6
(   COL1 NUMBER(5)      
,   COL2 VARCHAR2(30)   
,   CONSTRAINT TEST6_COL1_PK PRIMARY KEY (COL1)
,   CONSTRAINT TEST6_COL2_UK UNIQUE(COL2)
);
--==>> Table TBL_TEST6이(가) 생성되었습니다.

--○ 제약조건 확인
SELECT *
FROM VIEW_CONSTCHECK
WHERE TABLE_NAME='TBL_TEST6';
--==>>
/*
HR	TEST6_COL1_PK	TBL_TEST6	P	COL1		
HR	TEST6_COL2_UK	TBL_TEST6	U	COL2		
*/

--○ UK 지정 실습(③ 테이블 생성 이후 제약조건 추가)
-- 테이블 생성
CREATE TABLE TBL_TEST7
(   COL1 NUMBER(5)      
,   COL2 VARCHAR2(30)   
);
--==>> Table TBL_TEST7이(가) 생성되었습니다.

--○ 제약조건 확인
SELECT *
FROM VIEW_CONSTCHECK
WHERE TABLE_NAME='TBL_TEST7';
--==>> 조회 결과 없음

-- 제약조건 추가
ALTER TABLE TBL_TEST7
ADD ( CONSTRAINT TEST7_COL1_PK PRIMARY KEY(COL1)
    , CONSTRAINT TEST7_COL2_UK UNIQUE(COL2) );
--==>> Table TBL_TEST7이(가) 변경되었습니다.

--○ 제약조건 확인
SELECT *
FROM VIEW_CONSTCHECK
WHERE TABLE_NAME='TBL_TEST7';
--==>>
/*
HR	TEST7_COL1_PK	TBL_TEST7	P	COL1		
HR	TEST7_COL2_UK	TBL_TEST7	U	COL2		
*/

-- ■■■ CHECK(CK:C) ■■■ --

-- 1. 컬럼에서 허용 가능한 데이터의 범위나 조건을 지정하기 위한 제약조건,
--    컬럼에 입력되는 데이터를 검사하여 조건에 맞는 데이터만 입력될 수 있도록
--    처리하며, 수정되는 데이터 또한 검사하여 조건에 맞는 데이터로 수정되는 것만
--    허용하는 기능을 수행하게 된다.

--  2. 형식 및 구조
--  1) 컬럼 레벨의 형식
--  컬럼명 데이터타입[CONSTRAINT CONSTRAINT명] CHECK(컬럼 조건)

--  2) 테이블 레벨의 형식
--  컬럼명 데이터타입,
--  컬럼명 데이터타입,
--  CONSTRAINT CONSTRAINT명 CHECK(컬럼 조건)

--※ NUMBER(38)         까지.. 경은 0이 20개인데.. 38이면 크지.     
--   CHAR(2000)         까지...
--   VARCHAR2(4000)     까지...
--   NCHAR(1000)        까지...
--   NVARCHAR2(2000)    까지... 

--  CHECK~!!! 
--  COL1 NUMBER → NUMBER(38) -- 길이 명시 안하면 NUMBER 의 최대값을 쓰겠다는 의미
--  COL2 CHAR  → CHAR(1) -- 위와 달리 명시 안하면 1BYTE만큼의 길이를 쓰겠다는 뜻

--○ CK 지정 실습(1) 컬럼 레벨의 형식) 
CREATE TABLE TBL_TEST8
(   COL1 NUMBER(5)      PRIMARY KEY    
,   COL2 VARCHAR2(30)    
,   COL3 NUMBER(3)      CHECK(COL3 BETWEEN 0 AND 100)
);
--==>> Table TBL_TEST8이(가) 생성되었습니다.

--데이터 입력 
INSERT INTO TBL_TEST8(COL1, COL2, COL3) VALUES(1, '민주', 100);
INSERT INTO TBL_TEST8(COL1, COL2, COL3) VALUES(2, '채원', 101);   -->> 에러발생
-- 이름이 있는 형태로 제약조건을 형성하는 것이 좋음. 
INSERT INTO TBL_TEST8(COL1, COL2, COL3) VALUES(3, '은정', 80); 
INSERT INTO TBL_TEST8(COL1, COL2, COL3) VALUES(4, '승원', -10);   -->> 에러발생

COMMIT;

SELECT *
FROM TBL_TEST8;
--==>> 
/*
1	민주	100
3	은정	80
*/

--○ 제약조건 확인
SELECT *
FROM VIEW_CONSTCHECK
WHERE TABLE_NAME='TBL_TEST8';
--==>> 
/*
HR	SYS_C007023	TBL_TEST8	C	COL3	COL3 BETWEEN 0 AND 100	
HR	SYS_C007024	TBL_TEST8	P	COL1	
*/

--○ CK 지정실습(2)테이블 레벨의 형식) 
CREATE TABLE TBL_TEST9
(   COL1 NUMBER(5)          
,   COL2 VARCHAR2(30)    
,   COL3 NUMBER(3)     
, CONSTRAINT TEST9_COL1_PK PRIMARY KEY(COL1)
, CONSTRAINT TEST9_COL3_CK CHECK(COL3 BETWEEN 0 AND 100) 
);


--데이터 입력 
INSERT INTO TBL_TEST9(COL1, COL2, COL3) VALUES(1, '민주', 100);
INSERT INTO TBL_TEST9(COL1, COL2, COL3) VALUES(2, '채원', 101);   -->> 에러발생
-- 이름이 있는 형태로 제약조건을 형성하는 것이 좋음. 
INSERT INTO TBL_TEST9(COL1, COL2, COL3) VALUES(3, '은정', 80); 
INSERT INTO TBL_TEST9(COL1, COL2, COL3) VALUES(4, '승원', -10);   -->> 에러발생

COMMIT;

SELECT *
FROM TBL_TEST9;
--==>> 
/*
1	민주	100
2	채원	101
3	은정	80
4	승원	-10
*/

--○ 제약조건 확인
SELECT *
FROM VIEW_CONSTCHECK
WHERE TABLE_NAME='TBL_TEST9';

--○ CK 지정실습(3)테이블 레벨의 형식) 
CREATE TABLE TBL_TEST10
(   COL1 NUMBER(5)          
,   COL2 VARCHAR2(30)    
,   COL3 NUMBER(3)    
);
--==>> Table TBL_TEST10이(가) 생성되었습니다.

ROLLBACK; 

--○ 제약조건 확인
SELECT *
FROM VIEW_CONSTCHECK
WHERE TABLE_NAME='TBL_TEST10';
--==>> 조회 결과 없음

-- 이미 생성되어 있는 기존 테이블에 제약조건 추가 
ALTER TABLE TBL_TEST10
ADD ( CONSTRAINT TEST10_COL1_PK PRIMARY KEY(COL1)
    , CONSTRAINT TEST10_COL3_CK CHECK(COL3 BETWEEN 0 AND 100) );
--==>> Table TBL_TEST10이(가) 변경되었습니다.

--○ 제약조건 확인
SELECT *
FROM VIEW_CONSTCHECK
WHERE TABLE_NAME='TBL_TEST10';
--==>> 
/*
HR	TEST10_COL1_PK	TBL_TEST10	P	COL1		
HR	TEST10_COL3_CK	TBL_TEST10	C	COL3	COL3 BETWEEN 0 AND 100	
*/

--○ 실습을 위한 추가 테이블 생성
-- 테이블명 : TBL_TESTMEMBER

CREATE TABLE TBL_TESTMEMBER
(   SID NUMBER(5)
,   NAME VARCHAR2(30)
,   SSN CHAR(14)        -- 입력 형태 → 'YYNNDD-NNNNNNN'
,   TEL VARCHAR2(40)
);
--==>> Table TBL_TESTMEMBER이(가) 생성되었습니다.

 -- 문제

--  TBL_TESTMEMBER 테이블의 SSN(주민등록번호) 컬럼에서
--  데이터 입력 및 수정 시 성별이 유효한 데이터만 처리될 수 있도록
--  체크 제약조건을 추가할 수 있도록 한다. 
--  → 성별이 유효한 데이터 → 특정 자리 1, 2, 3, 4 허용
--  또한, SID 컬럼에는 PRIMARY KEY 제약조건 설정할 수 있도록 한다.

-- 데이터 입력
INSERT INTO TBL_TESTMEMBER(SID, NAME, SSN, TEL) 
VALUES(3, '고길동', '920709-1234567', '010-1212-3434');

INSERT INTO TBL_TESTMEMBER(SID, NAME, SSN, TEL) 
VALUES(4, '또치', '950812-2234567', '010-4545-6767');

INSERT INTO TBL_TESTMEMBER(SID, NAME, SSN, TEL) 
VALUES(5, '도우너', '030202-3234567', '010-7878-9999');

INSERT INTO TBL_TESTMEMBER(SID, NAME, SSN, TEL) 
VALUES(6, '희동이', '050709-4234567', '010-2323-4545');

INSERT INTO TBL_TESTMEMBER(SID, NAME, SSN, TEL) 
VALUES(5, '마이콜', '751212-5234567', '010-2580-2580');
/*
ORA-02290: check constraint (HR.TESTMEMBER_SSN_CK) violated
*/

COMMIT; 

SELECT *
FROM TBL_TESTMEMBER;
/*
3	고길동	920709-1234567	010-1212-3434
4	또치	950812-2234567	010-4545-6767
6	희동이	050709-4234567	010-2323-4545
5	도우너	030202-3234567	010-7878-9999
*/
    
SELECT *
FROM VIEW_CONSTCHECK
WHERE TABLE_NAME= 'TBL_TESTMEMBER';
--==>>
/*
HR	TESTMEMBER_SID_PK	TBL_TESTMEMBER	P	SID		
HR	TESTMEMBER_SSN_CK	TBL_TESTMEMBER	C	SSN	SUBSTR(SSN,8,1) IN ('1','2','3','4')	
*/

'IT > DBMS' 카테고리의 다른 글

Oracle - NOT NULL 실습  (1) 2025.07.09
Oracle - FOREIGN KEY 설정 실습  (0) 2025.07.09
Oracle - 정규화 과정  (2) 2025.07.08
Oracle- INTERSECT, MINUS(교집합/ 차집합)  (0) 2025.07.08
Oracle - UNION / UNION ALL  (1) 2025.07.08

관련글 더보기

댓글 영역