[상세표현법]
CREATE (OR REPLACE) (FORCE|"NOFORCE") VIEW 뷰명
AS 서브쿼리
(WITH CHECK OPTION)
(WITH READ ONLY)
1) OR REPLACE
: 해당 뷰가 존재하지 않으면 새로이 생성 / 해당 뷰가 존재하면 갱신시켜주는 옵션
2) FORCE / NOFORCE
FORCE
: 서브쿼리에 기술된 테이블이 존재하지 않아도 뷰가 생성
NOFORCE(생략시 기본값)
: 서브쿼리에 기술된 테이블이 반드시 존재해야만 뷰가 생성
3) WITH CHECK OPTION
: 서브쿼리의 조건절에 기술된 내용에 만족하는 값으로만 DML이 가능
(조건에 부합하지 않은 값으로 수정하는 경우 오류 발생)
4) WITH READ ONLY
: 뷰에 대해 조회만 가능(DML 수행불가)
< 시퀀스 SEQUENCE >
자동으로 번호 발생시켜주는 역할을 하는 객체
정수값을 자동으로 순차적으로 생성해줌
EX) 회원번호, 사번, 게시글 번호 등등 채번할 때 주로 사용할 예정
테이블명 : TB
뷰명 : VW
시퀀스명 : SEQ
트리거명 : TRG
CREATE SEQUENCE SEQ_TEST ;
SELECT * FROM USER_SEQUENCE; -- 이 계정이 소유하고 있는 시퀀스들에 대한 정보 조회용
-- USER_TABLES, USER_VIEWS
CREATE SEQUENCE SEQ_EMPNO
START WITH 300
INCREMENT BY 5
MAXVALUE 310
NOCYCLE
NOCACHE;
SELECT SEQ_EMPNO.CURRVAL FROM DUAL;
--> NEXTVAL를 한번이라도 수행하지 않는 이상 CURRVAL를 수행할 수 없음!
--> 왜? : CURRVAL은 마지막에 성공적으로 수행된 NEXTVAL의 값을 저장해서 보여주는 임시값
SELECT SEQ_EMPNO.NEXTVAL FROM DUAL; --> 300
SELECT SEQ_EMPNO.CURRVAL FROM DUAL;
SELECT SEQ_EMPNO.NEXTVAL FROM DUAL; --> 305
SELECT * FROM USER_SEQUENCES;
SELECT SEQ_EMPNO.CURRVAL FROM DUAL;
ALTER SEQUENCE SEQ_EMPNO
INCREMENT BY 10
MAXVALUE 400;
SELECT * FROM USER_SEQUENCES;
SELECT SEQ_EMPNO.NEXTVAL FROM DUAL; -- 320
-- SEQUENCE 삭제하기
DROP SEQUENCE SEQ_EMPNO;
-- 매번 새로운 사번이 발생되는 시퀀스 생성
CREATE SEQUENCE SEQ_EID
START WITH 300;
-- 사원이 추가될 때 실행할 INSERT문
INSERT INTO EMPLOYEE(EMP_ID, EMP_NAME, EMP_NO, JOB_CODE, HIRE_DATE)
VALUES(SEQ_EID.NEXTVAL, '홍길동', '910816-1209331', 'J2', SYSDATE);
INSERT INTO EMPLOYEE(EMP_ID, EMP_NAME, EMP_NO, JOB_CODE, HIRE_DATE)
VALUES(SEQ_EID.NEXTVAL, '홍길녀', '910816-2209331', 'J3', SYSDATE);
-- 사원에 대해 추가 "요청"시 실행할 SQL문
INSERT
INTO EMPLOYEE
(
EMP_ID
, EMP_NAME
, EMP_NO
, JOB_CODE
, HIRE_DATE
)
VALUES
(
SEQ_EID.NEXTVAL
, ? /사용자가 입력한 값/
, ? /사용자가 입력한 값/
, ? /사용자가 입력한 값/
, SYSDATE
)
:오라클 자체에 내장되어 있는 절차적인 언어
-- 간단하게 화면에 HELLO ORACLE 출력
SET SERVEROUTPUT ON
BEGIN
-- System.out.println("hello oracle")와 같음;
DBMS_OUTPUT.PUT_LINE('HELLO ORACLE');
END;
/
: 변수 및 상수 선언해놓는 공간(선언과 동시에 초기화도 가능)
일반타입변수, 레퍼런스타입 변수, ROW타입변수
[표현법]
변수명 (CONSTANT) 자료형 (:= 값);
DECLARE
EID NUMBER;
ENAME VARCHAR2(20);
PI CONSTANT NUMBER := 3.14;
BEGIN
-- EID := 800;
-- ENAME := '배장남';
-- 사용자에게 입력받은 값 출력하기
EID := &사번;
ENAME := '&이름';
DBMS_OUTPUT.PUT_LINE('EID:' || EID );
DBMS_OUTPUT.PUT_LINE('ENAME:' || ENAME );
DBMS_OUTPUT.PUT_LINE('PI:' || PI );
END;
/
[표현법]
변수명 테이블명.컬럼명%TYPE;
DECLARE
EID EMPLOYEE.EMP_ID%TYPE;
ENAME EMPLOYEE.EMP_NAME%TYPE;
SAL EMPLOYEE.SALARY%TYPE;
BEGIN
/*
EID := '200';
ENAME := '선동일';
SAL := 8000000;
*/
-- 사번이 200인 사원의 사번, 이름, 급여
SELECT EMP_ID , EMP_NAME , SALARY
INTO EID, ENAME, SAL -- 셀렉한 결과값을 변수값에 담고싶다면 INTO 붙여서 이렇게 하기!
FROM EMPLOYEE
-- WHERE EMP_ID = '200';
WHERE EMP_ID = &사번; -- 입력받은 값으로 조회하기
-- WHERE DEPT_CODE = '&부서코드';
=> 오류남 !!
왜? SELECT INTO를 이용해서 조회결과를 변수에 담고자 한다면 반드시 한 행으로 조회되어야 함!
DBMS_OUTPUT.PUT_LINE('EID:' || EID );
DBMS_OUTPUT.PUT_LINE('ENAME:' || ENAME );
DBMS_OUTPUT.PUT_LINE('SAL:' || SAL );
END;
/
----실습문제
/*
레퍼런스타입변수로 EID, ENAME, JCODE, SAL, DTITLE을 선언하고
각 자료형으로 EMPLOYEE의 EMP_ID, EMP_NAME, JOB_CODE, SALARY / DEPARTMENT의 DEPT_TITLE 컬럼들의 데이터타입을 참조하게끔
대체변수로 입력한 사원명과 일치하는 사원을 조회해서 각 변수에 대입 후 출력
*/
DECLARE
EID EMPLOYEE.EMP_ID%TYPE;
ENAME EMPLOYEE.EMP_NAME%TYPE;
JCODE EMPLOYEE.JOB_CODE%TYPE;
SAL EMPLOYEE.SALARY%TYPE;
DTITLE DEPARTMENT.DEPT_TITLE%TYPE;
BEGIN
SELECT EMP_ID, EMP_NAME, JOB_CODE, SALARY, DEPT_TITLE
INTO EID, ENAME, JCODE, SAL, DTITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
WHERE EMP_NAME = '&사원명';
DBMS_OUTPUT.PUT_LINE(EID || ', ' || ENAME || ', ' || JCODE || ', ' || SAL || ', ' || DTITLE);
END;
/
/*
1_3) ROW타입 변수
어떤 테이블의 한 행에 대한 모든 컬럼값을 다 담을 수 있는 변수
[표현법] 변수명 테이블명%ROWTYPE;
*/
DECLARE
E EMPLOYEE%ROWTYPE;
BEGIN
SELECT *
INTO E
FROM EMPLOYEE
--WHERE EMP_ID = 201;
WHERE EMP_NAME = '&사원명';
--DBMS_OUTPUT.PUT_LINE(E);
DBMS_OUTPUT.PUT_LINE('사번 : ' || E.EMP_ID);
DBMS_OUTPUT.PUT_LINE('사원명 : ' || E.EMP_NAME);
DBMS_OUTPUT.PUT_LINE('급여 : ' || E.SALARY);
DBMS_OUTPUT.PUT_LINE('연봉 : ' || E.SALARY * 12);
DBMS_OUTPUT.PUT_LINE('보너스 포함 연봉 : ' || (E.SALARY + E.SALARY * NVL(E.BONUS, 0)) * 12);
-- 출력문 안에 산술연산식, 함수식 기술 가능
END;
/