oracle

제약조건을 이용하기

말없는채플린씨 2009. 10. 8. 12:54
unique는 null값이 들어가
하지만 primary key는 null이 안들어가


SQL> DESC USER_CONSTRAINTS;
이름 널? 유형
----------------------------------------------------- -------- ------------------------------------
OWNER NOT NULL VARCHAR2(30)
CONSTRAINT_NAME NOT NULL VARCHAR2(30)
CONSTRAINT_TYPE VARCHAR2(1)
TABLE_NAME NOT NULL VARCHAR2(30)
SEARCH_CONDITION LONG
R_OWNER VARCHAR2(30)
R_CONSTRAINT_NAME VARCHAR2(30)
DELETE_RULE VARCHAR2(9)
STATUS VARCHAR2(8)
DEFERRABLE VARCHAR2(14)
DEFERRED VARCHAR2(9)
VALIDATED VARCHAR2(13)
GENERATED VARCHAR2(14)
BAD VARCHAR2(3)
RELY VARCHAR2(4)
LAST_CHANGE DATE
INDEX_OWNER VARCHAR2(30)
INDEX_NAME VARCHAR2(30)
INVALID VARCHAR2(7)
VIEW_RELATED VARCHAR2(14)

//제약조건을 주는것
오라클은 0이없어서 1부터 카운터
NOT NULL =NULL이 들어갈 수 없다

SQL> CREATE TABLE KOR(
2 NO NUMBER(3),//여기서 실수로 이렇게 된거야
3 CONSTRAINTS KOR_NO_PK PRIMARY KEY(NO));//그래서 이렇게 NO라고 표시를 해주는거야

SQL> CONN /AS SYSDBA;
연결되었습니다.
SQL> CREATE USER FLEX IDENTIFIED BY ADOBE DEFAULT TABLESPACE USERS;

사용자가 생성되었습니다.

SQL> GRANT CONNECT, RESOURCE TO FLEX;

권한이 부여되었습니다.

SQL> CONN FLEX/ADOBE
연결되었습니다.
SQL> SELECT * FROM TAB;

선택된 레코드가 없습니다.
//이런식으로 계정을 새로 하나 만든거야


1 CREATE TABLE PARENT(
2 PNO NUMBER(3) CONSTRAINTS PARENT_PNO_PK PRIMARY KEY,
3 PNAME VARCHAR2(10),
4* PSAL NUMBER(3))
SQL> /

테이블이 생성되었습니다.

SQL> ED
file afiedt.buf(이)가 기록되었습니다

1 CREATE SEQUENCE PARENT_SEQ
2 INCREMENT BY 2
3 START WITH 100
4* MAXVALUE 1000
SQL> /

시퀀스가 생성되었습니다.

//각각의 테이블 만들자



SQL> ALTER TABLE PARENT MODIFY PSAL NUMBER(30);

테이블이 변경되었습니다.

1* INSERT INTO PARENT VALUES(PARENT_SEQ.NEXTVAL,'전지현',10000)
SQL> /

1 개의 행이 만들어졌습니다.
//틀렸을때 ATER로 만들어서 이렇게 수정한다 나중에 시험문제 나온다


SQL> SELECT * FROM PARENT;

PNO PNAME PSAL
---------- ---------- ----------
100 전지현 10000
102 이영애 1000
104 신민아 20000


SQL> CREAT TABLE CHILD(

//해당되는 것만 지울 수 있도록 한 번 해봐

SQL> CREATE TABLE CHILD(
2 BLOOD CHAR(2) CONSTRAINTS CHILD_BLOOD_PK PRIMARY KEY,
3 CHARACTER VARCHAR2(10),
4 FATE VARCHAR2(100));

테이블이 생성되었습니다.

SQL> ALTER TABLE CHILD ADD PNO NUMBER(3) CONSTRAINTS CHILD_PNO_NN NOT NULL;
//부모키와 연동하기 위해서 자식테이블에 부모키와 연동할 수 있는
//외래키를 만들어서 JOIN이나 다른 것들을 할 수 있도록 해주는것..

테이블이 변경되었습니다.

SQL> ALTER TABLE CHILD ADD CONSTRAINTS CH_FK FOREIGN KEY(PNO) REFERENCES PARENT(PNO);
//제약조건 (오래키)를 안주고 끝마쳤기때문에 이렇게 ALTER TABLE을 이용해서
//수정을 하는것.. 외래키를 설정해주는것이라고 생각하면 된다

테이블이 변경되었습니다.


1* INSERT INTO CHILD VALUES('A','소심함','잘살팔자',104)
SQL> /

1 개의 행이 만들어졌습니다.

1* INSERT INTO CHILD VALUES('B','터프함','잘산다',100)


1 개의 행이 만들어졌습니다.

1* INSERT INTO CHILD VALUES('O','잘난척','그저그래',102)

1 개의 행이 만들어졌습니다.

1* INSERT INTO CHILD VALUES('AB','괴팍함','미지수',100)

1 개의 행이 만들어졌습니다.

SQL> SELECT * FROM CHILD;

BL CHARACTER
-- ----------
FATE
----------------------------------------------------------------------------------------------------
PNO
----------
A 소심함
잘살팔자
104

B 터프함
잘산다
100

O 잘난척
그저그래
102

AB 괴팍함
미지수
100

//각 혈액형별 성격을 구하고 부모키와 연결하는 폼을 만든다
이렇게해서 CASECADE를 사용해서 FOREIGN키 제약 조건을
TEST해보라고 한다
ONDELETE를 이용해서 FOREIGN키를 설정하는거라고 하는데
난 수업시간에 없었던듯해..ㅠㅜ


SQL> COLUMN FATE FORMAT A10;
SQL> SELECT * FROM CHILD;

BL CHARACTER FATE PNO
-- ---------- ---------- ----------
A 소심함 잘살팔자 104
B 터프함 잘산다 100
O 잘난척 그저그래 102
AB 괴팍함 미지수 100


SQL> DELETE FROM PARENT WHERE PNO='108';

1 행이 삭제되었습니다.

SQL> DELETE FROM PARENT WHERE PNO='104';
DELETE FROM PARENT WHERE PNO='104'
*
1행에 오류:
ORA-02292: 무결성 제약조건(FLEX.CH_FK)이 위배되었습니다- 자식 레코드가 발견되었습니다

//108은 자식에게 주어진게 없어
//하지만 104는 자식이 부모를 가지고 있어
그래서 이렇게 오류가 나오는거야


SQL> INSERT INTO CHILD VALUES('C','만나고싶다','미지수',100);

1 개의 행이 만들어졌습니다.
//100은 있지만 이렇게 외래키는 중복될 수 있다



////////////////////////////
ON DELET CASCADE이렇게 하는거다


SQL> ED
file afiedt.buf(이)가 기록되었습니다

1* ALTER TABLE CHILD DROP CONSTRAINTS CH_FK
//일단 제약 조건을 수정하기 위해서
//이렇게 지워주는거지..
//제약 조건을 수정하는게 무척힘들기 때문에
//차라리 제약 조건을 지우고 추가를 하는거지
SQL> /

테이블이 변경되었습니다.

SQL> ALTER TABLE CHILD ADD CONSTRAINTS CH_FK FOREIGN KEY(PNO) REFERENCES PARENT(PNO) on DELETE CASCA
DE
2 ;
//여기가 추가 부분이야
//너무 어려운 수정보다 지우고나서 이렇게 덧붙여 주는거지
//(지금현재 값이 들어가서 변경이 안되는거야 )
//값을 지우고 다시 수정하는건 너무 비효율적이기 때문이지)

테이블이 변경되었습니다.

SQL> DELETE FROM PARENT WHERE PNO=100;
1 행이 삭제되었습니다.
//PNO라는 NOT NULL키를 다시 FOREIGN키로 만들어서
//이것을 지울수 있도록 한거지...



SQL> ALTER TABLE CHILD DROP PRIMARY KEY;

테이블이 변경되었습니다.
//프라이머리키는 이런식으로 간단하게 삭제가 간단하다
단 하나만 있으니깐
다른건 이름까지 써야한다

SQL> ALTER TABLE PARENT DROP PRIMARY KEY;
ALTER TABLE PARENT DROP PRIMARY KEY
*
1행에 오류:
ORA-02273: 고유/기본 키가 외부 키에 의해 참조되었습니다
//죽고싶지만 자식때문에 죽을 수가 없다

같이 죽는 방법은
1* ALTER TABLE PARENT DROP PRIMARY KEY CASCADE
SQL> /

테이블이 변경되었습니다.
//CASCADE하나만써주면 부모와 자식이 같이 죽는게 된다

CASECADE의 활용을 잘 알아두어야 할것...
포린키를 지울때 이걸쓰는거야


1 SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE
2 FROM USER_CONSTRAINTS
3* WHERE TABLE_NAME IN('BLOOD','SALMO')
SQL> /

CONSTRAINT_NAME C
------------------------------ -
BLOOD_PBOOLD_PK P
SALMO_PSAL_PK P

이런식으로 조건을 검색하는것..



SQL> ALTER TABLE CHILD ADD CONSTRAINTS CHILD_BLOOD_PK PRIMARY KEY(BLOOD);

테이블이 변경되었습니다.
//PK를 지웠기때문에 이렇게 해준건야

SQL> INSERT INTO CHILD VALUES('B','나쁘다','ㅋㅋ',100);
INSERT INTO CHILD VALUES('B','나쁘다','ㅋㅋ',100)
*
1행에 오류:
ORA-00001: 무결성 제약 조건(FLEX.CHILD_BLOOD_PK)에 위배됩니다

//프라이머리키가 되어있으니깐 같은거 치면 이렇게 도지

SQL> ALTER TABLE CHILD DISABLE PRIMARY KEY;

테이블이 변경되었습니다.

//이런 프리머리키가 비활성화되고

SQL> INSERT INTO CHILD VALUES('B','나ㅃ쯔다','ㅋㅋ',100);

1 개의 행이 만들어졌습니다.

//비활성화되었기때문에 이렇게 프리머리키가 없기때문에
중복되게 들어가는 것이다


1* UPDATE CHILD SET BLOOD='A' WHERE FATE='ㅋㅋ'
SQL> /

1 행이 갱신되었습니다.

//현재 중복되게 들어가있기 때문에 이렇게 UPDATE를 해서 바꿔준다
하지만 현재 내가 넣은 값이 중복되는게 너무 많다
그래서 DELETE FROM을 사용해서 지웠다

SQL> ALTER TABLE CHILD ENABLE PRIMARY KEY;
ALTER TABLE CHILD ENABLE PRIMARY KEY
*
1행에 오류:
ORA-02437: (FLEX.CHILD_BLOOD_PK)을 검증할 수 없습니다 - 잘못된 기본 키입니다


SQL> SELECT * FROM CHILD;

BL CHARACTER FATE PNO
-- ---------- ---------- ----------
A 소심함 잘살팔자 104
O 잘난척 그저그래 102
B 좋은성격 나랑살자 104
AB 괴팍 미지수 110
A 나ㅃ쯔다 ㅋㅋ 100

SQL> DELETE FROM CHILD WHERE FATE='ㅋㅋ';

1 행이 삭제되었습니다.
//중복된것을 지우고 다시 프라이머리키를 지정해주어야한다

SQL> ALTER TABLE CHILD ENABLE PRIMARY KEY;

테이블이 변경되었습니다.


SQL> ALTER TABLE PARENT DISABLE PRIMARY KEY;

테이블이 변경되었습니다.
//다시 테이블을 이렇게 DISABLE을 시켜줘보자

SQL> INSERT INTO PARENT VALUES(114,'AIR',2000
2 );

1 개의 행이 만들어졌습니다.

SQL> ED
file afiedt.buf(이)가 기록되었습니다

1 INSERT INTO PARENT VALUES(114,'DIR',2000
2* )
SQL> /

1 개의 행이 만들어졌습니다.
//그럼 프라이머리 키가 비활성화되어서 다시 중복되게 데이터가
들어가겠지

SQL> COMMIT;

커밋이 완료되었습니다.
//중복되게 들어간 상태에서 COMMIT시킨다


@D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ADMIN


SQL> create table exceptions(row_id rowid,
2 owner varchar2(30),
3 table_name varchar2(30),
4 constraint varchar2(30));

테이블이 생성되었습니다.

SQL> DESC EXCEPTIONS;
이름 널? 유형
----------------------------------------------------- -------- -------------------
ROW_ID ROWID
OWNER VARCHAR2(30)
TABLE_NAME VARCHAR2(30)
CONSTRAINT VARCHAR2(30)

SQL>
1 SELECT ROWID R,PNO
2* FROM PARENT
SQL> /

R PNO
------------------ ----------
AAAM+IAAEAAAARFAAA 114
AAAM+IAAEAAAARFAAB 102
AAAM+IAAEAAAARFAAC 104
AAAM+IAAEAAAARFAAD 106
AAAM+IAAEAAAARFAAE 114
AAAM+IAAEAAAARFAAF 110

6 개의 행이 선택되었습니다.

//utlexcpt.sql 이파일이 중복된 데이터를 넣었을때 쉽게
구별하는것


SQL> ED
file afiedt.buf(이)가 기록되었습니다

1 SELECT ROWID R,PNO
2* FROM PARENT
SQL> /

R PNO
------------------ ----------
AAAM+IAAEAAAARFAAA 114
AAAM+IAAEAAAARFAAB 102
AAAM+IAAEAAAARFAAC 104
AAAM+IAAEAAAARFAAD 106
AAAM+IAAEAAAARFAAE 114
AAAM+IAAEAAAARFAAF 110

6 개의 행이 선택되었습니다.

SQL> SELECT ROWID,PNO,PNAME,PSAL
2 FROM PARENT;

ROWID PNO PNAME PSAL
------------------ ---------- ---------- ----------
AAAM+IAAEAAAARFAAA 114 AIR 2000
AAAM+IAAEAAAARFAAB 102 이영애 1000
AAAM+IAAEAAAARFAAC 104 신민아 20000
AAAM+IAAEAAAARFAAD 106 김연아 5000
AAAM+IAAEAAAARFAAE 114 DIR 2000
AAAM+IAAEAAAARFAAF 110 김시향 7000

6 개의 행이 선택되었습니다.
//공통된 아이디를 ROWID로 정열을 해주는것..
//이라고 생각된다..ㅠㅜ


SQL> ED
file afiedt.buf(이)가 기록되었습니다

1* ALTER TABLE PARENT ENABLE PRIMARY KEY EXCEPTIONS INTO EXCEPTIONS
SQL> /
ALTER TABLE PARENT ENABLE PRIMARY KEY EXCEPTIONS INTO EXCEPTIONS
*
1행에 오류:
ORA-02437: (FLEX.PARENT_PNO_PK)을 검증할 수 없습니다 - 잘못된 기본 키입니다
//공통된수를 이곳에다 저장을 해놓는거지
//그래서 공통되는 숫자를 한 눈에 볼 수 있게끔한거야


SQL> SELECT * FROM EXCEPTIONS;

ROW_ID OWNER TABLE_NAME
------------------ ------------------------------ ------------------------------
CONSTRAINT
------------------------------
AAAM+IAAEAAAARFAAE FLEX PARENT
PARENT_PNO_PK

AAAM+IAAEAAAARFAAA FLEX PARENT
PARENT_PNO_PK


SQL> SELECT * FROM PARENT;

PNO PNAME PSAL
---------- ---------- ----------
114 AIR 2000
102 이영애 1000
104 신민아 20000
106 김연아 5000
114 DIR 2000
110 김시향 7000

6 개의 행이 선택되었습니다.

SQL> SELECT * FROM PARENT
2 WHERE ROWID IN (SELECT ROW_ID FROM EXCEPTIONS);

PNO PNAME PSAL
---------- ---------- ----------
114 AIR 2000
114 DIR 2000
//서브쿼리를 사용해서 공통된 데이터를 불러오는거야

1* UPDATE PARENT SET PNO=119 WHERE PNAME='AIR'
SQL> /

1 행이 갱신되었습니다.
//중복되는 값을 119로 바꿔야 프리머리키를 할 수 있는거야

SQL> ALTER TABLE PARENT ENABLE PRIMARY KEY;

테이블이 변경되었습니다.
//이제 프리머리키를 바꾸는거지


'oracle' 카테고리의 다른 글

ORACLE 계정풀기  (0) 2009.11.19
view 공부하기  (0) 2009.10.08
group by 연습  (0) 2009.10.08
다중입력, rollback관련 연습  (0) 2009.10.08
서브쿼리 연습하기  (0) 2009.10.08