본문 바로가기

sql

12. 제약

728x90
반응형

제약(constraint)

* 테이블에 제약이 필요한 이유 ?

  "데이터의 품질을 높이기 위해서

             필요하다."

:

 잘못된 data 입력되지 못하도록

   설정을 하는 .

 

*제약의 종류(2 82페이지)

1. primary key--->중복, null 입력되지 않게.

2. unique-------->중복 입력 안되게.

3. not null------->null 입력 안되게.

4. check--------->지정된 data 입력되게.

5. foreign key--->부모테이블의

                       부모키 데이터만

                       입력될 있게

                       참조할 사용하는 제약.

PRIMARY KEY

중복,  NULL 입력방지하도록 제약을 걸어준다.

부모키라고 한다.

 

문제372.

아래의 테이블을 생성하는데

사원번호에 primary key 제약을 걸어서

생성하시오

 

테이블명: emp10

컬럼명: empno <<<여기 primary key

               ename

               sal

 

create table emp10

 (empno number(10) primary key,

  ename varchar2(20) ,

  sal number(10) );

 

 

문재373.

emp10 테이블에

아래의 데이터를 입력하시오!

 

사원번호    사원이름     월급

 7788          scott         3000

 7566          smith        2500

 7788          allen         5000

 

 

insert into emp10(empno, ename, sal)

values(7788, 'scott', 3000);

 

insert into emp10(empno, ename, sal)

values(7566, 'smith', 2500);

 

insert into emp10(empno, ename, sal)

values(7788, 'allen', 5000);

 

primary key 제약으로

empno 중복 들어가짐.

 

 

UNIQUE KEY

중복을 허용하지 않겠다는 제약이다.

 

문제374.

아래의 테이블을 생성하는데

ename unique 제약을

걸어서 생성하시오

 

테이블명: emp20

컬럼명 : empno, ename, sal

 

create table emp20

 (empno number(10),

  ename varchar2(20) unique,

  sal number(10) );

 

테이블명에 대고

F4 누르고

탭에서 제약조건 누르면

또는

select * from user_constraints

 where table_name='EMP20' ;

***** 대문자로 EMP20 써야 한다.

 

컬럼 확인으로 하면

select *

from user_cons_columns

where table_name='EMP20';

 

 

 

문제375.

emp20 테이블에 ename null

중복해서 입력해보시오

(ename unique 걸려있음)

 

insert into emp20(empno, ename, sal)

values(1111, null, 3000);

 

insert into emp20(empno, ename, sal)

values(2222, null, 4000);

 

***null 알수 없는 값이라

unique 걸어놔도 중복으로 잡힌다.

 

 

 

CHECK 제약

CHECK 걸어둔 조건만 입출력이 가능하다.

 

문제376.

아래의 테이블을 생성하는데

부서위치가 서울, 부산, 대전만

입력되도록 체크제약을 걸어서

생성하시오

 

테이블명: 50

컬럼명: empno

               ename

               sal

              loc <<<여기에 서울,부산,대전만

                   입력되도록 제약건다.

 

create table emp50

(empno number(10), ename varchar2(20),

   sal number(10),

   loc varchar2(20) check (loc in( '서울', '부산', '대전') );

 

 

시도해보면

insert into emp50

values(2122, 'scott', 4000, '광주');

제약때문에 에러뜸.

 

 

 

문제377.

아래의 테이블을 생성하는데

loc 제약을 걸어서

생성하시오!

 

테이블명: dept 100

컬럼명:  deptno

                 loc  <<<---NEW YORK, DALLAS, CHICAGO,

                                   BOSTON 입력되게

                                    생성하시오!

                dname

 

create table dept100

(deptno number(10),

loc varchar2(20) check(loc in('NEW YORK','DALLAS','CHICAGO','BOSTON')),

dname varchar2(20) );

 

 

문제378.

dept 테이블에 있는 모든 데이터를

dept 100 입력하시오

(deptno, loc, dname 순서로 컬럼생성)

 

insert into dept100(deptno, loc, dname)

select deptno, loc, dname

  from dept;

 

원래 dept 컬럼 순서가

deptno   dname   loc .

근데 새로 뽑을 dept100

deptno, loc, dname 으로

뽑고 싶다.

그래서 답처럼 컬럼지정을 해주되

순서도 똑같이 지정해준다.

**컬럼순서가 동일해야 한다 !!!!!!!!!!!!

 

 

문제379.

dept100 테이블의 loc 컬럼의 길이를

현재의 길이의

두배로 변경하시오.

 

desc dept100;

 

alter table dept100

modify loc varchar2(26);

 

deptno 10 번의 loc 부서를

washington 바꾸시오

 

 

문제380.

아래의 테이블을 생성하시오

(지정값만 입력/수정 되게 하는

 제약조건 이용해서)

 

테이블명: emp700

컬럼명:    empno

                  ename

                  sal <<<---0~9000 사이의 데이터만

                                입력/수정 되도록

 

create table emp700

(empno number(10),

 ename varchar2(20),

 sal number(10) check(sal between 0 and  9000));

 

 

 

 

 

 

문제381.

아래의 테이블을 생성하시오

 

테이블명: emp800

컬럼명:     empno

                 ename <<<----성씨가 김씨,이씨,박씨                                                     

                              입력되게                                                

                  sal

 

create table emp800

(empno number(10),

  ename varchar2(20) check

               (substr(ename,1,1) in ('','','')),

 sal number(10) );

 

 

insert into emp800

 values(1111, '김준구', 3000);

 

insert into emp800

values(2222,'장보겸', 3000);

**장씨는 안먹는 있당

 

또는

create table emp800

(empno number(10),

  ename varchar2(20) check

(ename like '%' or

 ename like '%' or

 ename like '%' ),          

 sal number(10) );

 

 

 

FOREIGN KEY 제약

 

 emp --------------------------dept

(자식)                              (부모)

deptno                            deptno

  10                                  10

  20                                  20

  20                                  30

  10                                  40

  30

    :

    :

 

outer join 써도 서로에게 없는 값까지

연결해서 출력할 있으나

성능이 되게 느려진다.

그냥 애초에

부모테이블 안에 있는 숫자만 입력되게끔

제약을 걸어놓는게 좋다.

 

설명: 만약 제약이 없어서 emp 테이블에

     deptno 80번과 같이

    dept 테이블의 deptno 없는 데이터가

    들어오게 되면

    나중에 join outer join 사용해야한다.

그런데 outer join 사용하게 되면

equi join 보다는 성능이 나빠질 있기 때문에

특별한 sql 튜닝방법이 필요해진다.

 

 

 

 

 

 emp900---------------------dept900

(자식)                              (부모)

deptno                            deptno

  10                                  10

  20                                  20

  20                                  30

  10                                  40

  30

    :

    :

 

문제382.

dept 테이블과 똑같은 테이블 구조와 데이터를 갖는

dept900 테이블을 생성하는데

deptno primary key 제약을 걸어서 생성하시오.

 

create table dept900

as select * from dept;

 

ALTER TABLE dept900

ADD CONSTRAINT DEPT900_deptno_pk primary KEY(deptno);

 

 

 

 

문제383.

emp 테이블과 똑같은 테이블 구조와 이터를 갖는 emp900 테이블을 생성하는데

deptno foreign key 제약을 걸고

dept900 deptno

참조하겠다라고 해서 만드시오

 

 

CREATE TABLE dept900

AS SELECT * FROM dept;

(똑같이 emp900 )

 

ALTER TABLE dept900

ADD CONSTRAINT DEPT900_deptno_pk primary KEY(deptno);

(이렇게 p(부모키) 제약 걸고)

 

alter table emp900

  add constraint emp900_deptno_fk foreign key(deptno)

   references dept900(deptno);

(이렇게 f 걸어주면 .)

 

 

 dept900_deptno_pk

 emp900_deptno_fk

   제약 이름이다

   바로 이해되게 부서명_컬럼명_제약종류로

   만들어준다.

 

 

insert into emp900(empno, ename, sal, deptno)

values(2919, 'jack', 4000, 90);

에러뜸! 부서번호 90 제약위반으로 안된다.

 

 

■이미 생성되어져 있는 테이블에

제약을 거는 방법

 

문제384.

사원테이블에 empno primary key 제약을

걸어보시오.

alter table emp

add constraint emp_empno_pk primary key(empno);

 

***중복, null 안걸려 있어야 제약걸기 가능

***이제 empno 에는 중복, null 걸림.

>>그게 p key 기능

 

create table emp434

 (empno number(10) constraint

                   emp434_empno_pk primary key,

ename varchar2(20) );

이렇게 테이블 생성할 때도

제약이름 만들어 있다.

이름 안정해주면 오라클이 알아서

sys 어쩌구로 정해준다.

 

 

 

 

문제385.

우리반 테이블에 empno

primary key 제약을 거시오

 

alter table emp2

add constraint emp2_empno_pk primary key(empno);

 

 

 

 

문제386.

사원 테이블의 ename unique 제약을 거시오

 

alter table emp

add constraint emp_ename_un unique(ename);

 

**만약 이름에 중복데이터 있으면 안된다.

 

 

 

문제387.

우리반 테이블에 ename unique 제약을

거시오

alter table emp2

add constraint emp2_ename_un unique(ename);

 

안된다!!!!!!

오전에 이상엽 추가했었다.

중복되서 유니크 건다.

 

 

 

문제388.

이상엽 데이터를 하나 지우고 다시 제약을 거시오

 

delete from emp2

where empno = 28

 

alter table emp2

add constraint emp2_ename_un unique(ename);

 

 

문제389.

아래의 데이터를 입력하시오

(제약 지우고)

 

select * from user_constraints;

해서 제약 있나 확인하고

 

alter table emp2

drop constraint emp2_ename_un;

 

alter table emp2

drop constraint emp2_empno_pk;

 

 

 

insert into emp2

select * from emp2

 where ename = '이상엽';

 

insert 행으로 넣는거.

alter 컬럼넣는거.

 

 

 

문제390.(이거 오늘의 마지막문제로

 뒤에 있음)

이상엽 데이터 개를 지우시오

 

delete from emp2

where rownum = 28;

안되지????????????

 

delete 하기 전에

select ename, rownum

 from emp2

  where rownum= 28;

 

값을 시도해보면

표시할 데이터가 없다고 나온다.

 

 

 

화면 캡처: 2018-10-29 오후 4:27

 

rownum 특징상

1번만 출력되고

나머지 번호는 출력할 없다.

 

 

 

 

문제391.

우리반 테이블에 나이컬럼에

제약을 거는데 20~55 까지만

입력/수정 있도록

check 제약을 거시오

 

alter table emp2

 add constraint emp2_age_ch

 check(age between 20

                                      and

                                                 55);

 

 

 

 

문제392.

우리반 테이블에 통신사 컬럼에 check 제약을 거는데

sk, lg, kt, cj hello 입력/수정 되겠금

체크제약을 거시오

 

대문자 sk 바꿔놓고 시작

update EMP2

set telecom = 'sk'

 where telecom='SK';

 

 

alter table emp2

 add constraint emp2_telecom_ch

check(telecom in('sk', 'lg', 'kt', 'cj hello'));

 

 

유이수 텔레콤데이터를 대문자로 변경하려하면

update emp2

 set telecom = 'SK'

  where ename = '유이수';

오류뜬다.

위에 제약 소문자 그대로 써야

입력/수정이 가능하다

(대소문자 가려야 한다)

 

 

 

 

문제393.

이메일을 입력/수정 할때에

@ . 있어야 입력/수정 되게끔

check 제약을 거시오

 

alter table emp2

add constraint emp2_email_ch

check(email like '%@%'

              or

       email like '%.%') ;

 

또는

check(email like '%@%.%')

 

 

갱신시도

update emp2

set email = 'dddd'

where ename= '유이수';

안나와

 

 

 

문제394.(오늘의 마지막 문제)

문제390번을 해결하시오.

문제390.

이상엽 데이터 개를 지우시오

delete from emp2

where rownum = 28;

 

 

alter table emp2

add rownum2 number(10);

 

update emp2

set rownum2 = rownum;

 

delete emp2

where rownum2= 28;

 

 

***rownum 특성상 1이상부터 출력되지 않는다.

rownum 내용이 필요한데

출력가능한 컬럼이 필요한거다

 

rownum2 컬럼을 만들어주고

update rownum 갱신한다음에

 

delete rownum2=28

하면 된다.

 

 

rowid

해당 row 유니크한 물리적 주소

 

AAAE / dAABAAALCxAAA

file번호 + block번호+ row번호

 

: king 지우기

 

delete emp

where rowid= 'AAAE+pAABAAALCxAAA';

 

rownumber 다르게

전부 rowid 출력 된다아아

 

rowid 알파벳이 오름차순으로 정렬된다.(나름의 규칙)

 

 

 

문제391.

숫자 1부터 100까지를 출력하는

쿼리를 작성하시오

 

select rownum

from dual

 connect by rownum < 101;

 

 

 

문제392.

위의 쿼리의 결과를

ctas(create table as select)

number100 이라는

테이블로 생성하시오

 

create table number100

as

select rownum as rn

  from dual

 connect by rownum <101;

 

*에러떴는데 별칭(alias) 쓰라고

오류떴음.

 

 

 

문제392.

dept테이블과

number100 cross 조인해서

deptno, loc, dname 출력 해보시오

(쿼리 짜는것 보다는

 결과가 어떤 컬럼으로, 몇개가 나올지

 예상해서 맞춰보기)

 

 select d.deptno, d.loc, d.dname

from dept d cross join number100 n100;

 

 

cross join = 컴마 찍는거

 

where 연결고리 주면

중복해서 출력한다.

 

 

 

 

문제393.

상엽이 데이터를 100 중복해서

출력하시오

 

SELECT e.*

FROM emp2 e cross JOIN NUMBER100 b

WHERE ename = '이상엽';

 

 

문제394.

emp2 테이블에 상엽이 데이터를 100 입력하시오!

 

insert into emp2

select e.*

 from emp2 e cross join number100 b

where ename='이상엽';

 

 

 

insert into emp2

select e.*

 from emp2 e cross join number100 b

where ename='장보겸';

 

 

insert into emp2

select e.*

 from emp2 e cross join number100 b

where ename='이상엽';

 

이상엽200, 장보겸100 추가

현재 이상엽201, 장보겸 101

 

 

문제395.

중복된 상엽이 데이터를 지우고

건만 남겨두시오!

 

 

DELETE FROM (SELECT *

                           FROM EMP2

                   WHERE ename = '이상엽')

 WHERE ROWID NOT IN (select min(rowid)     

  FROM EMP2

  GROUP BY ename);

 

 

******

(SELECT *

      FROM EMP2

      WHERE ename = '이상엽')

----->장보겸 이라는 중복데이터 100건도 있어서 출력값 한정시켜버림.

********************************************

 

 

min(rowid) 하면

이상엽 데이터에서

제일 먼저 입력 걸로 지정가능.

그걸 group by 하면 중복된 뽑힘

 

select ename, min(rowid) FROM EMP2 GROUP BY ename;

 

 

 

화면 캡처: 2018-10-30 오전 10:17

 

 

 

 

■제약 삭제

*scott 가지고 있는 테이블에 걸린

제약 리스트를 확인하시오

 

select * from user_cons_columns;

 

 

 

문제396.

emp900 테이블에 emp900_deptno_fk

 삭제하시오

 

alter table emp900

 drop constraint emp900_deptno_fk;

 

삭제 확인

select * from user_cons_columns;

 

 

문제397.

scott 가지고 있는 모든 제약을

삭제하시오

(DUAL 테이블 쓰면 안나옴. 왜일까요?)

 

 

select 'alter table  ' || table_name ||

       '  drop constraint  '  || constraint_name || ';'

from user_cons_columns;

 

나온 결과를

긁어서

실행돌리면 지워진다는 소리임

 

728x90
반응형