가. 해당 컬럼에 NULL 값 저장 방지
나. 컬럼-레벨 방식만 허용 ( 테이블-레벨 방식 비허용 )
다. null 값을 허용하는 기존 컬럼의 동작을 수정 -->
제약조건 추가가 아니라, 기존 조건의 수정
라. 제약조건명 형식: table_column_nn
예시)
CREATE TABLE [스키마].테이블명 (
컬럼명1 데이터타입 [CONSTRAINT 제약조건명] NOT NULL,
컬럼명2 데이터타입,
...
);
예제)
CREATE TABLE department7 (
deptno NUMBER(2)
CONSTRAINT department7_deptno_pk PRIMARY KEY,
dname VARCHAR2(15)
CONSTRAINT department7_dname_uk UNIQUE,
loc VARCHAR2(15)
CONSTRAINT department7_loc_nn NOT NULL
);
-- 널(null) 값 저장 불가
-- ORA-01400: cannot insert NULL into ("SCOTT"."DEPARTMENT7"."LOC")
INSERT INTO department7 (deptno, dname, loc)
VALUES (30, '인사', NULL);
(테이블에 들어가야하는 데이터를 한정 시킬 때 = 무결성 유지를 위해)
가. 해당 컬럼에 저장되는 데이터를 검사하여,
조건과 일치하는 데이터만 저장가능
나. 제약조건명 형식: table_column_ck
예시)
CREATE TABLE [스키마].테이블명 (
컬럼명1 데이터타입 [CONSTRAINT 제약조건명] CHECK(조건식),
컬럼명2 데이터타입,
...
);
예제)
CREATE TABLE department8 (
deptno NUMBER(2) ,
dname VARCHAR2(15)
CONSTRAINT
department8_dname_ck
CHECK( dname IN('개발','인사') ),
loc VARCHAR2(15)
);
예제에 데이터 넣기)
-- CHECK 제약조건에 부합
INSERT INTO department8 (deptno, dname, loc)
VALUES (10, '개발', '서울');
INSERT INTO department8 (deptno, dname, loc)
VALUES (20, '인사', '경기');
-- CHECK 제약조건에 위배
-- ORA-02290: check constraint (SCOTT.DEPARTMENT8_DNAME_CK) violated
INSERT INTO department8 (deptno, dname, loc)
VALUES (30, '개발부', '서울');
CREATE TABLE department9 (
deptno NUMBER(2) ,
dname VARCHAR2(15),
loc VARCHAR2(15),
CONSTRAINT
department9_dname_ck
CHECK( dname IN('개발','인사') ),
CONSTRAINT
department9_loc_ck
CHECK( loc IN('서울','경기') )
);
*제일 중요한 부분
두 테이블 간의 제약조건 확인
가. '외래키' 또는 '참조키' 라고 부름
나. 자식 테이블에서 부모 테이블을 참조할 때, 올바른 데이터만
참조 가능하도록 제약하는 방법
다. null 값 허용
라. 제약조건명 형식: table_column_fk
** 주의1 ** :
참조하는 부모테이블의 컬럼은, 반드시 1) 기본키(Primary Key)
또는 2) UNIQUE 제약조건이 설정된 컬럼 이어야 함!!!
PK/UK 아닌 컬럼을, 왜래키 제약조건으로 설정 시도 -> 오류발생
** 주의2 ** :
외래키는, 부모 테이블과 자식 테이블 간의 참조 무결성을 위한
제약조건이기 때문에, 자식 테이블에서 참조하게 되는 컬럼을
부모 테이블에서 기본키 또는 UNIQUE로 지정해 두어야 함!!!
-- deptno: 외래키(foreign key) or 참조키(reference key)
SELECT
empno,
deptno
FROM
emp;
-- deptno: 기본키(primary key)
SELECT
*
FROM
dept;
-- 참조 무결성 제약조건 위배
-- ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated - parent key not found
INSERT INTO emp (empno, ename, deptno)
VALUES (9000, 'John', 50);
-- USER_CONSTRAINTS 데이터 사전
-- 두 테이블 간의 제약조건 확인
DESC user_constraints;
SELECT
table_name,
constraint_type,
constraint_name,
r_constraint_name
FROM
user_constraints
WHERE
table_name IN ('DEPT', 'EMP');
예시)
CREATE TABLE [스키마].테이블명 (
컬럼명1 데이터타입 [CONSTRAINT 제약조건명] REFERENCES 부모테이블명(컬럼명),
컬럼명2 데이터타입,
...
);
CREATE TABLE dept02 (
deptno NUMBER(2) CONSTRAINT dept02_deptno_pk PRIMARY KEY,
dname VARCHAR2(15),
loc VARCHAR2(15)
);
INSERT INTO dept02 (deptno, dname, loc)
VALUES (10, '인사', '서울');
INSERT INTO dept02 (deptno, dname, loc)
VALUES (20, '개발', '광주');
INSERT INTO dept02 (deptno, dname, loc)
VALUES (30, '관리', '부산');
INSERT INTO dept02 (deptno, dname, loc)
VALUES (40, '영업', '경기');
COMMIT;
-- 참조하는 테이블 생성 후 데이터 넣는 예제)
CREATE TABLE emp02 (
empno NUMBER(4) CONSTRAINT emp02_empno_pk PRIMARY KEY,
ename VARCHAR2(15),
deptno NUMBER(2) CONSTRAINT emp02_deptno_fk REFERENCES dept02(deptno)
);
INSERT INTO emp02 (empno, ename, deptno)
VALUES (1000, 'John', 10);
INSERT INTO emp02 (empno, ename, deptno)
VALUES (2000, 'Smith', 20);
INSERT INTO emp02 (empno, ename, deptno)
VALUES (3000, 'Sam', NULL); --FK도 NULL과 중복을 허용
-- ORA-02291: integrity constraint (SCOTT.EMP02_DEPTNO_FK) violated - parent key not found
INSERT INTO emp02 (empno, ename, deptno)
VALUES (4000, 'Mike', 50); --존재하지 않는 값에 대한 참조 무결성이 깨진 데이터
COMMIT;
(컬럼과는 키워드가 다르다 .)
(FOREIGN KEY 키워드로 표현 )
예시)
CREATE TABLE [스키마].테이블명 (
컬럼명1 데이터타입,
컬럼명2 데이터타입,
...,
[CONSTRAINT 제약조건명] FOREIGN KEY(컬럼명n) REFERENCES 부모테이블명(컬럼명)
);
참조하는 테이블 생성 후 데이터 넣는 예제)
CREATE TABLE emp03 (
empno NUMBER(4) CONSTRAINT emp03_empno_pk PRIMARY KEY,
ename VARCHAR2(15),
deptno NUMBER(2),
CONSTRAINT emp03_deptno_fk FOREIGN KEY(deptno) REFERENCES dept02(deptno)
);
INSERT INTO emp03 (empno, ename, deptno)
VALUES (1000, 'John', 10);
INSERT INTO emp03 (empno, ename, deptno)
VALUES (2000, 'Smith', 20);
INSERT INTO emp03 (empno, ename, deptno)
VALUES (3000, 'Sam', NULL);
-- FOREIGN KEY 제약조건 위배
-- ORA-02291: integrity constraint (SCOTT.EMP03_DEPTNO_FK) violated - parent key not found
INSERT INTO emp03 (empno, ename, deptno)
VALUES (4000, 'Mike', 50);
COMMIT;
해결방법 2가지가 있다.
-- 특정부서(부모)를 참조하고 있는 사원(자식)들이 있으므로,
-- 부서를 삭제할 수 없음 (참조관계 존재)
-- ORA-02292: integrity constraint (SCOTT.EMP02_DEPTNO_FK) violated -
-- child record found
DELETE FROM dept02
WHERE deptno = 10; -- 부모 테이블의 특정부서 삭제
참조하는 부모테이블의 행이 삭제되면, 해당 행을 참조하는
자식테이블의 행도 연쇄삭제 됨.
CREATE TABLE emp02 (
empno NUMBER(4) CONSTRAINT emp02_empno_pk PRIMARY KEY,
ename VARCHAR2(15),
deptno NUMBER(2) CONSTRAINT emp02_deptno_fk
REFERENCES dept02(deptno) ON DELETE CASCADE
);
참조하는 부모 테이블의 행이 삭제되면, 해당 행을 참조하는 자식
테이블의 컬럼값을 NULL로 설정한다.
CREATE TABLE emp02 (
empno NUMBER(4) CONSTRAINT emp02_empno_pk PRIMARY KEY,
ename VARCHAR2(15),
deptno NUMBER(2) CONSTRAINT emp02_deptno_fk
REFERENCES dept02(deptno) ON DELETE SET NULL
);
PURGE; 란? 실수로 테이블을 삭제할 때 휴지통 개념으로 다시 살릴 수 있게 해줌 이걸 비움
flash back drop 이라고 함
ex) DROP TABLE emp02 PURGE; 이런식으로 씀
가. 삭제되는 테이블에 저장된 모든 데이터/관련 인덱스/외래키
제약조건을 제외한, 모든 제약조건이 같이 삭제된다.
나. 외래키 제약조건은 자동으로 삭제되지 않기 때문에, 자식 테이블
에서 부모테이블을 참조하는 상황에서, 부모 테이블을 삭제하면,
종속성에 의해서, 삭제가 안됨.
이 경우에 CASCADE CONSTRAINTS 옵션을 지정하여 삭제하면,
연쇄적으로 제약조건도 함께 삭제되기 때문에, 부모 테이블 삭제가능
예시)
DROP TABLE 테이블명 [CASCADE CONSTRAINTS];
그냥 삭제 예제)
-- 참조키에 의한 테이블 삭제불가.
-- 자식 테이블이 참조하는 상황에서, 부모 테이블 삭제시도
-- ORA-02449: unique/primary keys in table referenced by foreign keys
DROP TABLE dept02; -- 부모테이블 삭제불가
CASCADE CONSTRAINTS 키워드 추가)
-- 자식 테이블에 설정된, 외래키 제약조건까지 연쇄적으로 삭제하기 위해,
-- CASCADE CONSTRAINTS 옵션 추가.
DROP TABLE dept02 CASCADE CONSTRAINTS;
*해결법 - ORA-00942가 발생 할 경우 확인 해야 할 사항은 아래와 같습니다.
① 데이터베이스의 연결이 안되어 있음
② 테이블에 권한이 없음
③ 맞춤법이 오류 또는 실제로 테이블이 존재 하지 않음
④ 테이블의 앞에 소유자를 명시하여, SELECT 해야 함 ( SELECT * FROM 소유자.테이블명 )
가. 삭제된 테이블을 복구하는 방법 (from Oracle10g)
나. 테이블 삭제할 때, (DROP TABLE tablename;)
삭제된 테이블은 휴지통(RECYCLEBIN)이라는 특별한 객체에,
'BIN$' prefix가 붙은, 이름으로 저장됨.
다. 삭제된 테이블을 다시 복구하고 싶을 때, Flashback Drop
복구기술을 이용하여, 휴지통(RECYCKEBIN) 객체에서, 삭제된
테이블을 복구할 수 있다.
키워드)
SHOW RECYCLEBIN; -- RECYCLEBIN 객체정보 조회
--VSCODE에서는 못보고 DEVELOPER는 가능
FLASHBACK TABLE tablename TO BEFORE DROP; -- 삭제된 테이블 복구
DROP TABLE tablename PURGE; -- 테이블 완전삭제(복구불가)
PURGE RECYCLEBIN; -- RECYCLEBIN 객체정보 삭제
SHOW RECYCLEBIN; -- Only Oracle SQL*Developer
결과값:
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
-------------------- ------------------------------ ----------- -------------------
PK_EMP BIN$3s5PyjP58q3gUyAQAApeSw==$0 INDEX 2022-05-12:09:37:51
EMP BIN$3s5PyjP68q3gUyAQAApeSw==$0 TABLE 2022-05-12:09:37:52
BONUS BIN$3s5PyjP78q3gUyAQAApeSw==$0 TABLE 2022-05-12:09:37:52
PK_EMP BIN$3s5PyjP98q3gUyAQAApeSw==$0 INDEX 2022-05-12:09:38:07
EMP BIN$3s5PyjP+8q3gUyAQAApeSw==$0 TABLE 2022-05-12:09:38:07
BONUS BIN$3s5PyjP/8q3gUyAQAApeSw==$0 TABLE 2022-05-12:09:38:08
SALGRADE BIN$3s5PyjQA8q3gUyAQAApeSw==$0 TABLE 2022-05-12:09:38:08
PK_EMP BIN$3s5PyjQC8q3gUyAQAApeSw==$0 INDEX 2022-05-12:09:38:31
EMP BIN$3s5PyjQD8q3gUyAQAApeSw==$0 TABLE 2022-05-12:09:38:31
BONUS BIN$3s5PyjQE8q3gUyAQAApeSw==$0 TABLE 2022-05-12:09:38:32
SALGRADE BIN$3s5PyjQF8q3gUyAQAApeSw==$0 TABLE 2022-05-12:09:38:32
MYDEPT BIN$39NI7+21/FfgUyAQAArbrg==$0 TABLE 2022-05-25:08:59:03
MYEMP_MGR3 BIN$39NI7+22/FfgUyAQAArbrg==$0 TABLE 2022-05-25:10:28:08
DEPARTMENT_DEPTNO_PK BIN$3/yvu4h/akDgUyAQAApFjw==$0 INDEX 2022-05-27:10:22:41
DEPARTMENT BIN$3/yvu4iAakDgUyAQAApFjw==$0 TABLE 2022-05-27:10:22:41
EMP02_EMPNO_PK BIN$4Dcm8JcIpNvgUyAQAApFsA==$0 INDEX 2022-05-30:08:07:49
EMP02 BIN$4Dcm8JcJpNvgUyAQAApFsA==$0 TABLE 2022-05-30:08:07:49
EMP03_EMPNO_PK BIN$4Dcm8JcLpNvgUyAQAApFsA==$0 INDEX 2022-05-30:08:13:56
EMP03 BIN$4Dcm8JcMpNvgUyAQAApFsA==$0 TABLE 2022-05-30:08:13:56
EMP02_EMPNO_PK BIN$4Dcm8JcOpNvgUyAQAApFsA==$0 INDEX 2022-05-30:08:20:13
EMP02 BIN$4Dcm8JcPpNvgUyAQAApFsA==$0 TABLE 2022-05-30:08:20:13
DEPT02_DEPTNO_PK BIN$4DedVxUu1KLgUyAQAAo0Og==$0 INDEX 2022-05-30:08:40:56
DEPT02 BIN$4DedVxUv1KLgUyAQAAo0Og==$0 TABLE 2022-05-30:08:40:56
DEPT02_DEPTNO_PK BIN$4DedVxUx1KLgUyAQAAo0Og==$0 INDEX 2022-05-30:08:46:10
DEPT02 BIN$4DedVxUy1KLgUyAQAAo0Og==$0 TABLE 2022-05-30:08:46:10
FLASHBACK TABLE dept02 TO BEFORE DROP;
DROP TABLE dept02 PURGE;
PURGE RECYCLEBIN;
전체 테이블 조회 방법 3가지
1차로 지워진 테이블은 BIN$~~ 으로 표시된다.
가. 생성된 테이블의 구조를 변경
a. 컬럼의 추가/삭제
b. 컬럼의 타입/길이 변경
c. 컬럼의 제약조건 추가/삭제
나. ALTER TABLE 문장 사용
다. 테이블의 구조변경은 기존 저장된 데이터에 영향을 주게 됨
a. 기존 테이블에 새로운 컬럼 추가
b. 추가된 컬럼은, 테이블의 마지막에 추가
c. 데이터는 자동으로 null 값으로 저장됨
d. DEFAULT 옵션 설정도 가능
예시)
ALTER TABLE 테이블명
ADD ( 컬럼명1 데이터타입 [, ..., 컬럼명n 데이터타입] );
예제)
ALTER TABLE emp04
ADD (
email VARCHAR2(10),
address VARCHAR2(20)
);
(타입 크기 변경)
a. 기존 테이블에 기존 컬럼 변경
b. 컬럼의 타입/크기/DEFAULT값 변경가능
숫자/문자 컬럼의 전체길이의 증가/축소, 타입변경도 가능
c. DEFAULT 값 변경의 경우, 이후 입력되는 행에 대해서만 적용
예시)
ALTER TABLE 테이블명
MODIFY ( 컬럼명1 데이터타입 [, ..., 컬럼명n 데이터타입] );
예제)
ALTER TABLE emp04
MODIFY ( email VARCHAR2(40) );
ALTER TABLE emp04
MODIFY ( ename VARCHAR2(20) ); -- 줄였을때 안되고 오류나면 그게 다행이다
-- 줄였는데 짤리고 데이터 소실되면 그게 문제이다.
a. 기존 테이블에 기존 컬럼 삭제
b. 컬럼은 값의 존재여부와 상관없이, 무조건 삭제됨
c. 동시에 여러 컬럼삭제가 가능
d. 최소한 1개의 컬럼은 반드시 존재해야 됨
예시)
ALTER TABLE 테이블명
DROP ( 컬럼명1, [컬럼명n] );
예제)
ALTER TABLE emp04
DROP ( email ); --사용하고 있는지 안하고있는지 유의미한 컬럼인지 조심해야 함
가. 기존 테이블에 제약조건 추가
나. PK/FK/UK/CK 제약조건 추가 -> ALTER TABLE ADD 문 사용
다. NN 제약조건 추가 -> ALTER TABLE MODIFY 문 사용
라. 기존 테이블에 추가적인 제약조건도 추가 가능
예시)
ALTER TABLE 테이블명
ADD [CONSTRAINT 제약조건명] 제약조건타입(컬럼명);
전체적인 흐름의 예제)
-- 제약조건 없는 테이블 생성
CREATE TABLE dept03 (
deptno NUMBER(2),
dname VARCHAR2(15),
loc VARCHAR2(15)
);
-- 테이블에 제약조건 추가
ALTER TABLE dept03
ADD CONSTRAINT dept03_deptno_pk PRIMARY KEY(deptno);
-- 기본키 제약조건 추가 확인
SELECT
table_name,
constraint_type,
constraint_name,
r_constraint_name
FROM
user_constraints
WHERE
-- table_name IN ('DEPT03');
table_name IN ('DEPT');
예시)
ALTER TABLE 테이블명
MODIFY ( 컬럼명 데이터타입 [CONSTRAINT 제약조건명] NOT NULL );
예제)
-- NOT NULL 제약조건 추가
ALTER TABLE dept03
MODIFY ( dname VARCHAR2(15) CONSTRAINT dept03_dname_nn NOT NULL ); -- ALTER는 항상 신중하게 생각하고 해야함
(조회 -> 삭제)
가. 제약조건명 이용
USER_CONSTRAINTS, USER_CON_COLUMNS 조회하여,
제약조건명 조회
나. CASCADE 옵션
모든 종속적인 제약조건을 같이 삭제
다. 기본적으로, 제약조건명을 이용하여, 제약조건 삭제
라. 기본키(PK)와 UNIQUE(UK) 제약조건명 없이,
키워드만 사용하여 삭제가능
NN/CK/FK 제약조건 삭제 -> CONSTRAINT 제약조건명 지정하여 삭제
예시)
ALTER TABLE 테이블명
DROP PRIMARY KEY | UNIQUE(컬럼) | CONSTRAINT 제약조건명 [CASCADE];
SELECT
table_name,
constraint_type,
constraint_name,
r_constraint_name
FROM
user_constraints
WHERE
table_name IN ('DEPT03');
ALTER TABLE dept03
DROP PRIMARY KEY;
ALTER TABLE dept03
DROP CONSTRAINT dept03_deptno_pk;
ALTER TABLE dept03
DROP CONSTRAINT dept03_dname_nn;
예시 테이블 생성)
CREATE TABLE dept05 (
deptno NUMBER(2)
CONSTRAINT dept05_deptno_pk PRIMARY KEY,
dname VARCHAR2(15),
loc VARCHAR2(15)
);
INSERT INTO dept05 (deptno, dname, loc)
VALUES (10, '인사', '서울');
COMMIT;
-- ------------------------------------------------------
CREATE TABLE emp05 (
empno NUMBER(4)
CONSTRAINT emp05_empno_pk PRIMARY KEY,
ename VARCHAR2(15),
deptno NUMBER(2)
CONSTRAINT emp05_deptno_fk REFERENCES dept05(deptno)
);
INSERT INTO emp05 (empno, ename, deptno)
VALUES (1000, 'John', 10);
COMMIT;
참조키에 의한 기본 키 삭제 불가
자식테이블에서 부모테이블을 참조하고 있는 경우, 부모테이블의
기본키(PK)를 삭제하면, 에러가 발생
-- ORA-02273: this unique/primary key is referenced by some foreign keys
ALTER TABLE dept05
DROP PRIMARY KEY;
부모테이블의 PK/UK 제약조건 삭제시, 자식테이블의 FK 제약조건을 연쇄삭제위해
CASCADE 옵션 사용
ALTER TABLE dept05
DROP PRIMARY KEY CASCADE;
가. 기존 테이블의 제약조건을 필요에 의해 Enable/Disable 가능
나. 제약조건은 데이터의 무결성은 보장받을 수 있으나,
성능은 떨어뜨림
다. 예: 데이터의 무결성이 보장되는 방대한 데이터를, 테이블에
저장시 사용
* ENABLE: 제약조건 활성화
* DISABLE: 제약조건 비활성화
* CASCADE: 해당 제약조건과 관련된 모든 제약조건을 연쇄적으로 비활성화
예시)
ALTER TABLE 테이블명
DISABLE | ENABLE CONSTRAINT 제약조건명 [CASCADE];
PK 제약조건 비활성화 예제)
ALTER TABLE emp05
DISABLE CONSTRAINT emp05_empno_pk;
관계가 있으면 에러나는 예제)
ALTER TABLE dept
DISABLE CONSTRAINT pk_dept; 다른테이블과의 관계없을 때 비활성화
PK 제약조건 활성화 예제)
-- ALTER TABLE emp05
-- ENABLE CONSTRAINT emp05_empno_pk;
ALTER TABLE dept
ENABLE CONSTRAINT pk_dept;
classpath 뭐하는거냐?
우리가 만든 소스에서 사용한 모든클래스(*.class)를 찾아가는 경로들..
개발환경을 사용하니까 따로 정해놓지 않아도 자동으로 bin폴더에 지정이 된다.
허나 옛날에는 일일히 경로를 지정해줘야 했다.
파워셀 에서 명령어: javac -classpath C:경로~
상대경로
내가 정해놓은 위치(classpath)까지 올라가서 거기서부터 찾는 경로
절대경로
bin 파일 컴파일된 클래스가 모든 패키지별로 정렬되어있다.
properties 예제)
public class PropertiesExample {
public static void main(String[] args) throws Exception {
//1. properties 객체 생성
Properties properties = new Properties();
System.out.println(properties);
// --- // 연속적으로 메소드를 부르는 것을 메소드체이닝 이라고 부름 Method Chaining
String path = PropertiesExample.
class. // clazz 객체가 얻어짐 java.lang.clazz
getResource("database.properties"). // java.net.URL
// getResource("../../../resource/database.properties"). // 상대경로 방식: 같은 위치가 아니라면 clazz의 기준점으로 classPath(Lombok 있는 곳)까지 가서 경로를 알려줘야한다.
// getResource("/resource/database.properties"). // 절대경로 방식: 어차피 bin폴더는 자동으로 classPath로 추가되기 때문에 경로를 구구절절 적을 필요없다.
getPath(); // java.lang.String
System.out.println(path);
//// ---
// path = URLDecoder.decode(path, "utf-8");
//// ---
// properties.load(new FileReader(path)); //중요
//// ---
//
// String driver = properties.getProperty("driver");
// String url = properties.getProperty("url");
// String username = properties.getProperty("username");
// String password = properties.getProperty("password");
//
// System.out.println("driver : " + driver);
// System.out.println("url : " + url);
// System.out.println("username : " + username);
// System.out.println("password : " + password);
} // main
}// end class
- jar 파일관리
jar 파일이란?
자바 언어로 만든 압축/해체 프로그램JDK 의 bin 폴더안에 들어있는 명령어
XXXXX.jar 파일이 있다면, 아래와 같이 관리
(1) XXXX.jar 파일의 내용 보기
C:\temp> jar tvf XXXX.jar
(2) XXXX.jar 파일의 해체(압축풀기)
C:\temp> jar xvf XXXX.jar
(3) XXXX.jar 파일의 생성(압축생성)
C:\temp> jar cvf XXXX.jar 파일1 파일2 디렉토리1 디렉토리2