web.xml 설정
<error-page>
<error-code>400</error-code>
<location>/WEB-INF/views/error/400.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/views/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/views/error/500.jsp</location>
</error-page>
컨트롤러
/error400 , 500.. 404 요청시(오류 발생시) tile-config.xml에
<definition name="*/*" extends="tiles-layout">
<put-attribute name="body" value="/WEB-INF/views/{1}/{2}.jsp" />
</definition>
로 흡수되어 컨트롤러의 해당하는 메서드 실행됨
package kr.or.ddit;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ErrorController {
@RequestMapping(value="/error/400")
public String error400() {
return "error/400";
}
@RequestMapping(value="/error/404")
public String error404() {
return "error/404";
}
@RequestMapping(value="/error/500")
public String error500() {
return "error/500";
}
}
--PL/SQL(절차적 언어로써의 질의어)
--User Defined Function(사용자 정의 함수)
/*
CREATE OR REPLACE FUNCTION 사용자정의함수명(바인드변수...)
반환값이 있음. 일반 오라클 내장함수
( ex) LENGTH, SUBSTR, INSTR, TO_CHAR...)처럼 사용할 수 있음
반환할 데이터 타입을 RETURN으로 선언해야 함
실행영역에서도 RETURN문이 있어야 함
*/
/
SET SERVEROUTPUT ON;
/
--P_EMP_NUM : 바인드 변수(IN/OUT) => 파라미터를 받거나 보내거나..
CREATE OR REPLACE FUNCTION FN_MEMNAME(P_EMP_NUM IN VARCHAR2)
RETURN VARCHAR2
IS
--SCALAR변수
R_NM VARCHAR2(100);
BEGIN
--PL/SQL에서의 SELECT에는 꼭 INTO문이 있어야 함
SELECT NM INTO R_NM
FROM EMP
WHERE EMP_NUM = P_EMP_NUM;
DBMS_OUTPUT.PUT_LINE('생성 완료!');
RETURN R_NM;
END;
/
--자동차번호를 통해 고객의 명을 알고자 할때..
--33너1122
--EQUI JOIN
SELECT *
FROM CAR A, CUS B
WHERE A.CUS_NUM = B.CUS_NUM
AND A.CAR_NUM = '33너1122';
--INNER JOIN(ANSI표준)
SELECT B.CUS_NM
FROM CAR A INNER JOIN CUS B ON(A.CUS_NUM = B.CUS_NUM)
WHERE A.CAR_NUM = '33너1122';
/
CREATE OR REPLACE FUNCTION FN_GET_CUS_NM(P_CAR_NUM IN VARCHAR2)
RETURN VARCHAR2
IS
--REFERENCE변수
--VARCHAR2(100)
R_CUS_NM CUS.CUS_NM%TYPE;
BEGIN
SELECT B.CUS_NM INTO R_CUS_NM
FROM CAR A INNER JOIN CUS B ON(A.CUS_NUM = B.CUS_NUM)
WHERE A.CAR_NUM = P_CAR_NUM;
RETURN R_CUS_NM;
END;
/
SELECT CAR_NUM, MK, PY, DRI_DIST, FN_GET_CUS_NM(CAR_NUM) CUS_NM FROM CAR;
/
/*
Package
꾸러미, 포장한 상품이라는 의미
업무상 관련 있는 것을 하나로 묶어서 사용
여러 변수, Cursor, Function, Procedure, Exception을 묶어서 캡슐화함
선언부와 본문 이렇게 두 부분으로 나뉨
선언부는 패키지에 포함될 변수, Procedure, function 등을 선언함
*/
/
--선언부
CREATE OR REPLACE PACKAGE PKG_GET_NM
IS
FUNCTION FN_MEMNAME(P_EMP_NUM IN VARCHAR2) RETURN VARCHAR2;
FUNCTION FN_GET_CUS_NM(P_CAR_NUM IN VARCHAR2) RETURN VARCHAR2;
END;
/
--본문
CREATE OR REPLACE PACKAGE BODY PKG_GET_NM
IS
--첫번째 함수 BODY
FUNCTION FN_MEMNAME(P_EMP_NUM IN VARCHAR2) RETURN VARCHAR2
IS
--SCALAR변수
R_NM VARCHAR2(100);
BEGIN
--PL/SQL에서의 SELECT에는 꼭 INTO문이 있어야 함
SELECT NM INTO R_NM
FROM EMP
WHERE EMP_NUM = P_EMP_NUM;
DBMS_OUTPUT.PUT_LINE('생성 완료!');
RETURN R_NM;
END FN_MEMNAME;
--두번째 함수BODY
FUNCTION FN_GET_CUS_NM(P_CAR_NUM IN VARCHAR2) RETURN VARCHAR2
IS
R_CUS_NM CUS.CUS_NM%TYPE;
BEGIN
SELECT B.CUS_NM INTO R_CUS_NM
FROM CAR A INNER JOIN CUS B ON(A.CUS_NUM = B.CUS_NUM)
WHERE A.CAR_NUM = P_CAR_NUM;
RETURN R_CUS_NM;
END FN_GET_CUS_NM;
END PKG_GET_NM;
/
SELECT CAR_NUM, MK, PY, DRI_DIST, PKG_GET_NM.FN_GET_CUS_NM(CAR_NUM) CUS_NM FROM CAR;
<실습>
/*
PLS-00201: identifier 'DBMS_CRYPTO' must be declared
는 권한 문제이네요..
sys의 DBMS_CRYPTO 패키지의 실행권한을 유저에게 주시면 됩니다.
GRANT EXECUTE ON DBMS_CRYPTO TO 사용자;
GRANT EXECUTE ON DBMS_CRYPTO TO PUBLIC;
GRANT EXECUTE ON DBMS_OBFUSCATION_TOOLKIT TO PUBLIC;
*/
/
SET SERVEROUTPUT ON;
/
CREATE OR REPLACE PACKAGE pkg_crypto
IS
FUNCTION encrypt ( input_string IN VARCHAR2 ) RETURN RAW;
FUNCTION decrypt ( input_string IN VARCHAR2 ) RETURN VARCHAR2;
END pkg_crypto;
/
CREATE OR REPLACE PACKAGE BODY pkg_crypto
IS
-- 에러 발생시에 error code 와 message를 받기 위한 변수 지정.
SQLERRMSG VARCHAR2(255);
SQLERRCDE NUMBER;
FUNCTION encrypt (input_string IN VARCHAR2 )
RETURN RAW
IS
key_data_raw RAW(64);
converted_raw RAW(64);
encrypted_raw RAW(64);
BEGIN
-- 들어온 data 와 암호 키를 각각 RAW 로 변환한다.
converted_raw := UTL_I18N.STRING_TO_RAW(input_string , 'AL32UTF8');
key_data_raw := UTL_I18N.STRING_TO_RAW( '12345678' , 'AL32UTF8');
-- DBMS_CRYPTO.ENCRYPT 로 암호화 하여 encrypted_raw 에 저장.
encrypted_raw := DBMS_CRYPTO.ENCRYPT( src => converted_raw ,
typ => DBMS_CRYPTO.DES_CBC_PKCS5 , -- typ 부분만 변경하면 원하는 알고리즘을 사용할 수 있다. key value byte 가 다 다르니 확인해야 한다.
key => key_data_raw ,
iv => NULL);
RETURN encrypted_raw;
END encrypt;
FUNCTION decrypt (input_string IN VARCHAR2 )
RETURN VARCHAR2
IS
converted_string VARCHAR2(64);
key_data_raw RAW(64);
decrypted_raw VARCHAR2(64);
BEGIN
key_data_raw := UTL_I18N.STRING_TO_RAW( '12345678' , 'AL32UTF8');
decrypted_raw := DBMS_CRYPTO.DECRYPT( src => input_string ,
typ => DBMS_CRYPTO.DES_CBC_PKCS5 ,
key => key_data_raw ,
iv => NULL);
-- DBMS_CRYPTO.DECRYPT 수행 결과 나온 복호화 된 raw data를 varchar2로 변환하면 끝!
converted_string := UTL_I18N.RAW_TO_CHAR(decrypted_raw, 'AL32UTF8');
RETURN converted_string;
END decrypt ;
END pkg_crypto;
/
--grant execute on ddit.pkg_crypto to 계정;
/
--패키지가 정상적으로 생성되었는지 테스트
SELECT PKG_CRYPTO.ENCRYPT('test') from dual;
SELECT PKG_CRYPTO.DECRYPT(PKG_CRYPTO.ENCRYPT('test')) FROM DUAL;
--테스트 테이블 생성
CREATE TABLE TEST_CRYPTO (ID INT , PWD VARCHAR2(64)) ;
INSERT INTO TEST_CRYPTO VALUES (1, PKG_CRYPTO.ENCRYPT('a1234b'));
INSERT INTO TEST_CRYPTO VALUES (2, PKG_CRYPTO.ENCRYPT('c1234d'));
COMMIT;
SELECT ID
, PKG_CRYPTO.DECRYPT(PWD)
FROM TEST_CRYPTO;