/*- 11_sequence.sql -*/

/*
 * # 시퀀스 ( sequence )
 * - 테이블 내의 유일한 숫자를 자동으로 생성하는 자동 번호 생성기.
 * - 해를 구분하는 기본키가 유일한 값을 갖도록 테이블 내의 유일한 숫자를 자동으로 생성가능.
 *   CREATE SEQUENCE sequence_name 
 *          START WITH            -> 시퀀스 시작 번호 지정
 *          INCREMENT BY          -> 연속적인 시퀀스 번호의 증가치
 *          MAXVALUE | NOMAXVALUE -> 최대값 지정
 *          MINVALUE | NOMINVALUE -> 최소값 지정
 *          CYCLE | NOCYCLE       -> 시퀀스가 최대값까지 완료되면 시작값에 다시시작
 *          CACHE | NOCACHE       -> 메모리상의 시퀀스 값 관리
 * - CURRVAL : 현재값 반환
 *   NEXTVAL : 현재 시퀀스 값의 다음 값 반환
 * - 한 번 값을 정해놓으면 변경 불가능. 
 */
 
-- 시퀀스 객체 생성
CREATE SEQUENCE TEST_SEQ
START WITH 1
INCREMENT BY 1;

-- NEXTVAL 로 새로운 값 생성
SELECT TEST_SEQ.NEXTVAL FROM DUAL;

-- 시퀀스 객체의 현재값
SELECT TEST_SEQ.CURRVAL FROM DUAL;

-- 시퀀스 객체 삭제
DROP SEQUENCE TEST_SEQ;

-- 연습용 테이블
DROP TABLE EMP01 PURGE;

CREATE TABLE EMP01 (
EMPNO NUMBER(4) CONSTRAINT PK_SEQ_EMPNO PRIMARY KEY,
ENAME VARCHAR2(10),
HIREDATE DATE
);
DESC EMP01;

-- EMP01 테이블의 EMPNO 컬럼 시퀀스 객체 생성.
CREATE SEQUENCE EMP01_EMPNO_SEQ START WITH 1 INCREMENT BY 1 MAXVALUE 1000;

-- 데이터 추가
INSERT INTO EMP01 VALUES (EMP01_EMPNO_SEQ.NEXTVAL, 'ManA', SYSDATE);
INSERT INTO EMP01 VALUES (EMP01_EMPNO_SEQ.NEXTVAL, 'ManB', SYSDATE);

SELECT * FROM EMP01;

DROP SEQUENCE EMP01_EMPNO_SEQ;

/*
 * # 시퀀스 수정
 * - ALTER SEQUENCE 는 START WITH 절 빼고, CREATE SEQUENCE 와 구조가 동일.
 *   START WITH 옵션은 변경할 수 없고, 다시 시작하려면 시퀀스를 삭제하고 다시 생성.
 */

-- 연습용 테이블
CREATE TABLE SEQTEST(
SNO NUMBER(2) PRIMARY KEY
);

DESC SEQTEST;

-- SEQTEST 테이블 SNO 컬럼에 적용하는 시퀀스 객체 생성.
CREATE SEQUENCE SEQTEST_SEQ START WITH 1 INCREMENT BY 1 MAXVALUE 3;

-- 데이터 추가 
INSERT INTO SEQTEST VALUES (SEQTEST_SEQ.NEXTVAL);
INSERT INTO SEQTEST VALUES (SEQTEST_SEQ.NEXTVAL);
INSERT INTO SEQTEST VALUES (SEQTEST_SEQ.NEXTVAL);

--INSERT INTO SEQTEST VALUES (SEQTEST_SEQ.NEXTVAL); : ERROR ! MAXVALUE=3;

SELECT * FROM SEQTEST;

-- 시퀀스 최대값 수정 
ALTER SEQUENCE SEQTEST_SEQ MAXVALUE 10;
INSERT INTO SEQTEST VALUES (SEQTEST_SEQ.NEXTVAL);

DROP TABLE SEQTEST PURGE;
DROP SEQUENCE SEQTEST_SEQ;

/* QUIZ */
-- 부서정보를 가지는 테이블을 작성하세요 : 부서번호, 부서명, 지역 
CREATE TABLE DEPT_INFO (
DEPTNO NUMBER(2) CONSTRAINT PK_DEPTNO PRIMARY KEY,
DNAME VARCHAR2(14),
LOC VARCHAR2(13)
);
DESC DEPT_INFO;
DROP TABLE DEPT_INFO PURGE;
-- > 부서번호는 SEQUENCE를 사용해서 적용 ( 초기값 10, 10씩 증가 )
SELECT * FROM DEPT_INFO;

CREATE SEQUENCE DEPT_SEQ START WITH 10 INCREMENT BY 10 MAXVALUE 10000;
DROP SEQUENCE DEPT_SEQ;

INSERT INTO DEPT_INFO VALUES (DEPT_SEQ.NEXTVAL, 'ManA', 'LONDAN');
INSERT INTO DEPT_INFO VALUES (DEPT_SEQ.NEXTVAL, 'ManB', 'SEOUL');
INSERT INTO DEPT_INFO VALUES (DEPT_SEQ.NEXTVAL, 'ManC', 'CANADA');

SELECT DEPT_SEQ.CURRVAL FROM DUAL;