◈ Out(외부) Join 

 - equijoin 문장들의 한가지 제약점은 그것들이 조인을 생성하려 하는 두 개의 테이블의 두개 컬럼에서 공통된 값이 없다면 테이블로부터 테이터를 Return하지 않는 다는 것입니다. 
 - 정상적으로 조인 조건을 만족하지 못하는 행들을 보기위해 outer join을 사용합니다. 
    Outer join 연산자 "( + )"입니다. 
 - 조인시킬 값이 없는 조인측에 "( + )"를 위치 시킵니다
 - Outer join 연산자는 표현식의 한 편에만 올 수 있습니다. 


--------------------------------------------------------------------


예제1) 일반 조인의 경우 

SQL> SELECT DISTINCT(a.deptno), b.deptno
         FROM emp a, dept b
         WHERE  a.deptno = b.deptno

DEPTNO     DEPTNO
---------- ----------
        10         10
        20         20
        30         30


예제2)out join을 했을 경우

SQL>  SELECT DISTINCT(a.deptno), b.deptno
          FROM emp a, dept b
          WHERE  a.deptno(+) = b.deptno

 DEPTNO     DEPTNO
 -------     ----------
     10         10
     20         20
     30         30
                 40

※ 다음의 쿼리를 한번 잘 보시기 바랍니다. 

SQL>  SELECT DISTINCT(a.deptno), b.deptno
          FROM emp a, dept b
          WHERE  a.deptno(+) = b.deptno
               AND a.ename LIKE '%';

    DEPTNO     DEPTNO
---------- ----------
        10         10
        20         20
        30         30

쿼리 결과를 잘 보면 out조인이 되지 않은 것을 알 수 있습니다.
위 쿼리를 out조인이 되기 위해서는 아래와 같이 고쳐야 합니다


SQL> SELECT DISTINCT(a.deptno), b.deptno
         FROM emp a, dept b
         WHERE  a.deptno(+) = b.deptno
              AND a.ename(+) LIKE '%'

    DEPTNO     DEPTNO
---------- ----------
        10         10
        20         20
        30         30
                    40

OUT조인 조건이 걸려있는 테이블에는 다른 조건절이 들어와도 
똑같이 OUT조인 연산자인 (+)를 해주어야 합니다.  



--------------------------------------------------------------------



Oracle9i 부터는 ANSI/ISO SQL표준인 LEFT OUTER JOIN , RIGHT OUTER JOINFULL OUTER JOIN를 지원 합니다.



--------------------------------------------------------------------


☞ LEFT OUTER JOIN 
 왼쪽 테이블에 조인시킬 컬럽의 값이 없는 경우 사용합니다. 
  
SQL>SELECT DISTINCT(e.deptno), d.deptno 
    FROM dept d LEFT OUTER JOIN emp e 
    ON d.deptno = e.deptno; 
  
  
☞ RIGHT OUTER JOIN 
 - 오른쪽에 테이블에 조인시킬 컬럽의 값이 없는 경우 사용합니다. 
  
SQL>SELECT DISTINCT(a.deptno), b.deptno 
    FROM emp a RIGHT OUTER JOIN dept b 
    ON a.deptno = b.deptno; 
  
  
☞ FULL OUTER JOIN 
양쪽 테이블에 다 outer join을 거는것을 TWO-WAY OUTER JOIN 또는 FULL OUTER JOIN이라 합니다. 
  
SQL>SELECT DISTINCT(a.deptno), b.deptno 
    FROM emp a FULL OUTER JOIN dept b 
    ON a.deptno = b.deptno; 
  
-- 위 세 문장의 결과는 아래와 같습니다. 
    DEPTNO     DEPTNO 
---------- ---------- 
        10         10 
        20         20 
        30         30 
                   40 
  
LEFT OUTER JOIN과 RIGHT OUTER JOIN의 테이블 순서를 바꾸어 가면서 테스트를 하시면 쉽게 이해를 하실 수 있습니다. 






sql 참고

http://www.oracleclub.com/lecture/1021


'Database > Oracle' 카테고리의 다른 글

[Oracle] SUBSTR, INSTR  (0) 2013.12.05
[OUTER JOIN] sql outer join  (0) 2013.12.04
Alter Table - 컬럼 추가, 삭제, 변경  (0) 2013.02.13
Oracle 자동 증가 컬럼(Sequence) 사용  (0) 2013.02.06
Oracle auto-increment trigger 형식  (0) 2013.02.06

ERD

우선 erwin을 실행 시킨다.

   

File > New

Logical/Physical 클릭 , Oracle 9.x

   

Model > Model Properties > Notation

Logical Notation, Physical Notation :: IE 로 설정

   

상단의 Logical 부분을 우선 Physical 로 변경 해준다

   

왼쪽에서 2번째 그림으로 테이블을 Create 한다

   

아래와 같이 생성한 뒤

   

Logical로 변경 해준다.

   

그 다음 위 테이블 DEP_NUM 오른쪽 마우스 클릭 > attributes 클릭

   

New > 눌러서 column 정보와 이름을 기입한다

   

Primary key check 하면 설정 됨

   

Datatype 설정 후 OK

   

Format > Table Display > Column DataType 체크

Format > Table Display > Null Option 체크

   

Physical 일 땐 위와 같이 나온다.

   

   

Logical 일 땐 위와 같이 나온다.

ibatis 에서 resultMap 형식으로 값을 vo에 담아 return 할 시, 간혹 값이 넘어 오지 않는 경우가 있다.

이 경우에는 resultMap property 값과 select 하고자 한 column 값과 정확히 일치 해주어야 return 이 가능해진다


무슨 말이냐.. 하면 예를 들어보자.


<resultMap id="BoardListResult" class="boardVo">

<result property="num" column="num" columnIndex="1" />

<result property="author" column="author" columnIndex="2" />

<result property="title" column="title" columnIndex="3" />

<result property="content" column="content" columnIndex="4" />

<result property="writeday" column="writeday" columnIndex="5" />

<result property="readcnt" column="readcnt" columnIndex="6" />

  <result property="repRoot" column="rep_root" columnIndex="7" /><!--이부분을 삭제-->

<result property="repIndent" column="rep_indent" columnIndex="8" /><!--당연히 columnIndex 값을 7 로 변경-->

</resultMap>


<select id="list" resultMap="BoardListResult" parameterClass="boardVo">

<![CDATA[

SELECT 

num

, author

, title

, content

, writeday

, readcnt

, rep_indent

FROM( 

            SELECT 

... 중략

</select>


위와 같이 했을 때 값을 return 해 올 수 없다. 그 이유는 select 한 값은 rep_indent 까지 딱 7개의 column을 들고 오는데 반해 resultMap은 repRoot라는 property 값이 선언 되어 있다.


이럴 때 select 할 때 rep_root를 찾던가, 아니면 resultMap에 선언 되어 있는 repRoot result 태그를 삭제 해주면 잘 return 하는 것을 볼 수 있다.

iBatis 는 실제적으로 많이 사용 하고 있거나, 그렇지 않으면 앞으로 사용 할 때

굉장히 헷갈리는 부분이 있다.


바로 어떻게 value object와 column name을 맵핑 시킬 것인가,

혹은 값들을 어떻게 jsp에 뿌릴 것 인가, 즉슨 자바 코드에 어떻게 담아서 운반 할 것인가

에 대해 많은 고민이 있다.


이제 때에 맞는 iBatis value 맵핑에 대해 알아보자.


우선, 게시판을 예로 들겠다.

1. 글 작성 후 글을 DB에 insert 시킬 시

여기선 아마 write.jsp 라는 페이지에서 form값을 vo에 담아 controller 에다 넘겨 줄 것이다.


// vo 객체를 인스턴스화 하여 가져온다

<typeAlias alias="boardVo" type="jh.board.vo.BoardVO"/>


<insert id="write" parameterClass="boardVo">


이렇게 parameterClass는 vo값을 insert만 하고 아무런 result값도 가져오지 않을 때 주로 쓰인다.


2. 글 목록들을 Select 할 때

여기선 객체 하나만 가져오는게 아니라, 객체의 리스트 제네릭을 리턴 받는다.


<resultMap id="BoardResult" class="boardVo">

<result property="num" column="num" columnIndex="1" />

<result property="author" column="author" columnIndex="2" />

<result property="title" column="title" columnIndex="3" />

<result property="content" column="content" columnIndex="4" />

<result property="writeday" column="writeday" columnIndex="5" />

<result property="readcnt" column="readcnt" columnIndex="6" />

</resultMap>


<select id="list" resultMap="BoardResult" parameterClass="boardVo">


resultMap을 이용하여 boardVo 객체의 겟/셋 변수명과 DB의 column 명을 맵핑 한 후

그 결과를 조회하여 resultMap 을 Controller단 까지 넘겨 받는다.


여기서 유심히 볼 것은 그저 select만 한다면 paramterClass가 필요 없다.

하지만 검색 시 검색명과 검색값을 select 문에 넣기 위해 paramterClass가 또 쓰여 졌다.


3. 상세글이나 업데이트 시


<select id="retrieve" resultMap="BoardResult">


<select id="updateForm" resultMap="BoardResult">


위와 마찬가지로 resultMap을 사용 하여 값을 return 받아 프레젠테이션 층에 넘겨 준다.


4. 그런데 resultClass 는 어디서 사용 될까 ?


<select id="count" resultClass="Integer">

SELECT 

COUNT( num )

FROM board

</select>


위와 같이 그냥 Integer(정수형) 으로 num의 count만 받고 싶다면 저렇게 쓰면 된다.


물론 Delete문과 같이 리턴 받을게 없고 그저 삭제만 시킨다 함은 resultMap, resultClass를 쓸 필요가 없는 것이다.


요약 하자면,

resultMap - Object를 return 받을 때 사용

resultClass - Integer 등 1개의 value형을 return 받을 때 사용

parameterClass - Object를 ibatis DML(#num#, #title#)문에 적용 시키고 싶을 때 사용



# test table 생성

create table test (

name varchar(10)

);


# test table에 osy란 number(10)타입의 컬럼 추가

SQL > alter table test add(osy number(10));


# test table에 osy 컬럼명을 osy88 로 컬럼명 변경

SQL > alter table test rename column osy to osy88;


# test table에 osy88 컬럼 데이터 타입 변경

SQL > alter table test modify(osy88 varchar(10));


# test table에 osy88 컬럼 삭제

SQL > alter table test drop(osy88);

'Database > Oracle' 카테고리의 다른 글

[OUTER JOIN] sql outer join  (0) 2013.12.04
Outer Join (LEFT, RIGHT, FULL OUTER JOIN)  (0) 2013.12.03
Oracle 자동 증가 컬럼(Sequence) 사용  (0) 2013.02.06
Oracle auto-increment trigger 형식  (0) 2013.02.06
Oracle Tablespace  (0) 2013.01.13

Unique Key를 생성하는 방법은 DBMS마다 차이가 있다.
MS-SQL은 IDENTITY를, MySQL은 auto_increment와 같이 쉽게 사용할 수 있는 방법이 있는데 오라클에서는 Sequence를 사용하여 다음과 같이 유사하게 구현할 수 있다


------------------------------------------------------------------------------------------

1. 자동증가컬럼을 사용하고자 하는 MYTABLE테이블을 생성한다.


       CREATE TABLE MYTABLE
               (ID NUMBER, NAME VARCHAR2(20));


2. CREATE SEQUENCE 라는 문장을 사용하여 SEQ_ID라는 이름의 시퀀스를 만든다.


       CREATE SEQUENCE SEQ_ID INCREMENT BY 1 START WITH 10000;

      -- INCREMENT BY 1 : 증가값은 1
      -- START WITH 10000 :  10000부터 증가


3.  테이블에 데이터 입력시에는 NEXTVAL이라는 슈도 칼럼(Pseudo-column)을 이용하여 시퀸스를 사용한다.


       INSERT INTO MYTABLE VALUES( SEQ_ID.NEXTVAL, '홍길동');

       -- CURRVAL : 현재 값을 반환 합니다. . 
       -- NEXTVAL : 현재 시퀀스값의 다음 값을 반환 합니다. 


------------------------------------------------------------------------------------------

sequence와 trigger를 통해서 auto-increment를 생성 할 수 있다.


먼저, auto-increment를 시행해볼 table을 만든다.


CREATE TABLE templet(

seq NUMBER PRIMARY KEY,

str1 VARCHAR2(256) NOT NULL,

str2 VARCHAR2(256) NOT null

)


seq가 1로부터 시작해서 1씩 증가할 수 있도록 sequence를 생성한다. 


CREATE SEQUENCE templet_sequence

START WITH 1

INCREMENT BY 1;


테이블에 insert 할 때마다 seq column에 이 sequence 를 적용시킬 수 있도록 trigger를 걸어보도록 하자.


CREATE OR REPLACE TRIGGER templet_trigger

BEFORE INSERT

ON templet

REFERENCING NEW AS NEW

FOR EACH ROW

BEGIN

SELECT TEMPLET_SEQUENCE.NEXTVAL INTO :new.seq FROM dual;

END;


이제 테이블에 새로운 row가 insert 될 때마다 이 test_trigger가 실행될 것이고, 결과적으로 seq가 자동으로 1씩 증가하게 된다.

오라클의 Tablespace.

테이블이 저장되는 공간.

오라클에서는 테이블스페이스라고 하여 테이블이 저장될 공간을 먼저 만들고 나서 테이블을 생성 한다

각각의 테이블을 테이블스페이스별로 나누어서 관리와 퍼포먼스의 향상을 가지고 오는것 이다


테이블스페이스를 생성하면 정의된 용량만큼 미리확보한 테이블 스페이스가 생성 되어지고 생성되어진 테이블 스페이스에 테이블 데이터가 저장 된다.


테이블스페이스 생성

create tablespace webacc

datafile 'C:\oracle\product\10.2.0\oradata\orcl\test.dbf' size 100m

default storage

(INITIAL    10K

NEXT      10K

MINEXTENTS 2

MAXEXTENTS 50

PCTINCREASE 50)

;


테이블스페이스 자동확장
alter tablespace webacc
add datafile 'C:\oracle\product\10.2.0\oradata\orcl\test02.dbf' size 200m
autoextend on next 10m
maxsize 500m
;

Oracle을 사용하다보면 종종 유저 Lock이 걸리곤 한다. 


일단 root 권한인 sys로 oracle에 접속하자

sqlplus sys/manager as sysdba;


유저 락 해제

alter user soctt2 account unlock;


유저의 락을 해제하면 비번과 권한설정을 새로 해주어야 한다.

alter user scott2 identified by tiger2;

grant create session to scott2;

grant create sequence to scott2;

grant create table to scott2;

grant drop any table to scott2;


그리고 테이블을 생성/삭제 하려는데, 테이블스페이스의 권한설정이 새로 생성한 scott2에게 없다고 에러를 낸다.

그럴 때는 scott2 유저에게 테이블스페이스의 권한까지 주자.

alter user scott2 quota unlimited on webacc;


이렇게하면 에러가 나지 않을 것이다

+ Recent posts