Everything has an expiration date
[Oracle - PL/SQL] 20231106 [프로그램 소스] 본문
20231106_01_scott(plsql).sql
SELECT USER
FROM DUAL;
--==>> SCOTT
--○ TBL_STUDENTS 테이블에서 전화번호와 주소 데이터를 수정하는(변경하는)
-- 프로시저를 작성한다.
-- 단, ID 와 PW 가 일치하는 경우에만 수정을 진행할 수 있도록 처리한다.
-- 프로시저명 : PRC_STUDENT_UPDATE()
/*
실행 예)
EXEC PRC_STUDENT_UPDATE('moon', 'java000', '010-9999-9999', '강원도 횡성');
--==>> 데이터 수정 Ⅹ
EXEC PRC_STUDENT_UPDATE('moon', 'java006$', '010-9999-9999', '강원도 횡성');
--==>> 데이터 수정 ○
*/
SELECT *
FROM TBL_STUDENTS;
--==>>
/*
ID NAME TEL ADDR
moon 문정환 010-9999-9999 강원도 횡성
wool 정한울 010-2222-2222 서울 강남구
*/
SELECT *
FROM TBL_IDPW;
--==>>
/*
ID PW
moon java006$
wool java006$
*/
CREATE OR REPLACE PROCEDURE PRC_STUDENT_UPDATE2
( 아이디
, 패스워드
, 전화번호
, 주소
)
IS
BEGIN
END;
-- 두 개의 테이블은 부모 자식 관계가 아니라 1대1 관계이므로
-- 어떤 테이블에서 ID를 가져오는지는 상관이 없다.
-- 방법 1.
CREATE OR REPLACE PROCEDURE PRC_STUDENT_UPDATE2
( V_ID IN TBL_IDPW.ID%TYPE
, V_PW IN TBL_IDPW.ID%TYPE -- STUDENTS 테이블에 존재하지 않는다.
, V_TEL IN TBL_STUDENTS.TEL%TYPE
, V_ADDR IN TBL_STUDENTS.ADDR%TYPE
)
IS
V_PW2 TBL_IDPW.PW%TYPE;
-- 사용자가 실제로 입력한 값 : V_PW
-- 사용자가 입력한 값과 실제로 비교해야할 원래의 PW : V_PW2
-- 입력한 패스워드와, 실제 패스워드가 맞는지를 확인할 FLAG 변수.
-- 오라클에서는 boolean 타입이 없으므로, NUMBER로 구성.
-- 임의의 값을 우선 담아둔다.
V_FLAG NUMBER := 0; -- 패스워드일치 : 1 / 패스워드불일치 : 2
BEGIN
-- * 이렇게 구한 결과값을 변수에 담아둬야, 나중에 비교할 대상으로 사용 가능하다.
SELECT PW INTO V_PW2
FROM TBL_IDPW
WHERE ID = V_ID;
IF (V_PW = V_PW2) -- 패스워드 일치
THEN V_FLAG := 1;
ELSE
V_FLAG := 2; -- 패스워드 불일치
END IF;
-- V_FLAG 가 2 이면, WHERE의 두 번째 조건 (V_FLAG = 1)이 참이 아니므로
-- 업데이트가 발생하지 않는다.
UPDATE TBL_STUDENTS
SET TEL = V_TEL, ADDR = V_ADDR
WHERE ID = V_ID
AND V_FLAG = 1;
COMMIT;
END;
--==>> Procedure PRC_STUDENT_UPDATE2이(가) 컴파일되었습니다.
-- 방법 2.
CREATE OR REPLACE PROCEDURE PRC_STUDENT_UPDATE3
( V_ID IN TBL_IDPW.ID%TYPE
, V_PW IN TBL_IDPW.ID%TYPE
, V_TEL IN TBL_STUDENTS.TEL%TYPE
, V_ADDR IN TBL_STUDENTS.ADDR%TYPE
)
IS
BEGIN
UPDATE (
SELECT T1.ID, T1.PW, T2.TEL, T2.ADDR
FROM TBL_IDPW T1 JOIN TBL_STUDENTS T2
ON T1.ID = T2.ID
) T
SET T.TEL = V_TEL, T.ADDR = V_ADDR
WHERE T.ID = V_ID
AND T.PW = V_PW;
COMMIT;
END;
--==>> Procedure PRC_STUDENT_UPDATE3이(가) 컴파일되었습니다.
--○ TBL_INSA 테이블을 대상으로 신규 데이터 입력 프로시저를 작성한다.
-- NUM, NAME, SSN, IBSADATE, CITY, TEL, BUSEO, JIKWI, BASICPAY, SUDANG 으로 구성된 컬럼 중
-- NUM(사원번호) 항목을 제외한 데이터 입력 시
-- 해당 항목의 값은 기존 부여된 사원 번호의 마지막 번호 그 다음 번호를
-- 자동으로 입력 처리할 수 있는 프로시저로 구성한다.
-- 프로시저명 : PRC_INSA_INSERT()
/*
실행 예)
EXEC PRC_INSA_INSERT('최혜인', '970812-2234567', SYSDATE, '서울', '010-2509-1783'
, '개발부', '대리', 2000000, 2000000); -- 이백만, 이백만
→ 위와 같이 프로시저 호출 및 실행
1061 최혜인 970812-2234567 2023-11-06 서울 010-2509-1783 개발부 대리 2000000 2000000
의 데이터가 신규 입력된 상황
*/
CREATE OR REPLACE PROCEDURE PRC_INSA_INSERT
( V_NAME TBL_INSA.NAME%TYPE
, V_SSN TBL_INSA.SSN%TYPE
, V_IBSADATE TBL_INSA.IBSADATE%TYPE
, V_CITY TBL_INSA.CITY%TYPE
, V_TEL TBL_INSA.TEL%TYPE
, V_BUSEO TBL_INSA.BUSEO%TYPE
, V_JIKWI TBL_INSA.JIKWI%TYPE
, V_BASICPAY TBL_INSA.BASICPAY%TYPE
, V_SUDANG TBL_INSA.SUDANG%TYPE
)
IS
V_NUM TBL_INSA.NUM%TYPE;
BEGIN
-- #1 V_NUM에 마지막 사원번호 + 1의 값을 대입해 준다.
SELECT (MAX(NUM) + 1) INTO V_NUM
FROM TBL_INSA;
-- #2 입력받은 매개변수와, V_NUM을 대입하여
-- TBL_INSA 테이블에 새로운 데이터를 입력해 준다.
INSERT INTO TBL_INSA(NUM, NAME, SSN, IBSADATE, CITY, TEL, BUSEO, JIKWI, BASICPAY, SUDANG)
VALUES(V_NUM, V_NAME, V_SSN, V_IBSADATE, V_CITY, V_TEL, V_BUSEO, V_JIKWI, V_BASICPAY, V_SUDANG);
COMMIT;
END;
--==>> Procedure PRC_INSA_INSERT이(가) 컴파일되었습니다.
--[선생님 풀이!!!]
CREATE OR REPLACE PROCEDURE PRC_INSA_INSERT2
( V_NAME TBL_INSA.NAME%TYPE
, V_SSN TBL_INSA.SSN%TYPE
, V_IBSADATE TBL_INSA.IBSADATE%TYPE
, V_CITY TBL_INSA.CITY%TYPE
, V_TEL TBL_INSA.TEL%TYPE
, V_BUSEO TBL_INSA.BUSEO%TYPE
, V_JIKWI TBL_INSA.JIKWI%TYPE
, V_BASICPAY TBL_INSA.BASICPAY%TYPE
, V_SUDANG TBL_INSA.SUDANG%TYPE
)
IS
V_NUM TBL_INSA.NUM%TYPE;
BEGIN
--★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
-- NUM 값을 얻어냈을 때, 만약 NULL 값이라면...(레코드가 아무것도 들어가있지 않다면!!)
-- 사원번호가 계속해서 NULL로 처리되므로 이를 0으로 처리하라는 것을 명령해야 한다.
--★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
-- 기존 부여된 사원번호의 마지막 번호
SELECT MAX(NVL(NUM, 0)) INTO V_NUM
FROM TBL_INSA;
INSERT INTO TBL_INSA(NUM, NAME, SSN, IBSADATE, CITY, TEL, BUSEO, JIKWI, BASICPAY, SUDANG)
VALUES(V_NUM + 1, V_NAME, V_SSN, V_IBSADATE, V_CITY, V_TEL, V_BUSEO, V_JIKWI, V_BASICPAY, V_SUDANG);
-- 커밋
COMMIT;
/*
SELECT MAX(NVL(NUM, 0)) + 1 INTO V_NUM
FROM TBL_INSA;
INSERT INTO TBL_INSA(NUM, NAME, SSN, IBSADATE, CITY, TEL, BUSEO, JIKWI, BASICPAY, SUDANG)
VALUES(V_NUM, V_NAME, V_SSN, V_IBSADATE, V_CITY, V_TEL, V_BUSEO, V_JIKWI, V_BASICPAY, V_SUDANG);
COMMIT;
*/
END;
--==>> Procedure PRC_INSA_INSERT2이(가) 컴파일되었습니다.
-- [이 구문이 불가능한 이유.(에러 발생!)]***************************************
--V_NUM := (SELECT NAME
-- FROM TBL_INSA
-- WHERE NUM=1001);
--
-- 동일한 메모리 영역이라면 값을 담을 수 있을텐데 서로 다르다.
-- PLSQL 변수 선언 메모리 구조랑
-- 쿼리문을 통해 값을 얻어내는 메모리 구조랑 다르다.
-- 따라서, INTO 를 통해 값을 담아내야 한다.
--****************************************************************************
--※ 20231106_02_scott.sql 파일을 참조하여
-- TBL_상품, TBL_입고 테이블을 대상으로
-- TBL_입고 테이블에 데이터 입력 시(즉, 입고 이벤트 발생 시)
-- TBL_상품 테이블의 해당 상품에 대한 재고수량이 함ㄲ 변동될 수 있는 기능을 가진
-- 프로시저를 작성한다.
-- 단, 이 과정에서 입고 번호는 자동 증가 처리한다. (시퀀스 사용 안함)
-- TBL_입고 테이블 구성 컬럼은
-- 입고번호, 상품코드, 입고일자, 입고수량, 입고단가이며
-- 프로시저 호출을 통해 전달할 파라미터는 상품코드, 입고수량, 입고단가이다.
-- 프로시저명 : PRC_입고_INSERT(상품코드, 입고수량, 입고단가)
DESC TBL_입고;
CREATE OR REPLACE PROCEDURE PRC_입고_INSERT
( V_상품코드 TBL_입고.상품코드%TYPE
, V_입고수량 TBL_입고.입고수량%TYPE
, V_입고단가 TBL_입고.입고단가%TYPE
)
IS
V_입고번호 TBL_입고.입고번호%TYPE;
BEGIN
-- ① INSERT → TBL_입고
-- INSERT INTO TBL_입고(입고번호, 상품코드, 입고일자, 입고수량, 입고단가)
-- VALUES(1, 'H001', SYSDATE, 30, 400);
SELECT NVL(MAX(입고번호), 0) + 1 INTO V_입고번호
FROM TBL_입고;
INSERT INTO TBL_입고(입고번호, 상품코드, 입고일자, 입고수량, 입고단가)
VALUES(V_입고번호, V_상품코드, SYSDATE, V_입고수량, V_입고단가);
-- ② UPDATE → TBL_상품
-- UPDATE TBL_상품
-- SET 재고수량 = 기존재고수량 + 입고수량 -- CHECK~!!!
-- WHERE 상품코드 = 'H001';
UPDATE TBL_상품 TS
SET TS.재고수량 = TS.재고수량 + V_입고수량
WHERE TS.상품코드 = V_상품코드;
COMMIT;
END;
--==>> Procedure PRC_입고_INSERT이(가) 컴파일되었습니다.
--[선생님 풀이!!!]
CREATE OR REPLACE PROCEDURE PRC_입고_INSERT2
( V_상품코드 TBL_상품.상품코드%TYPE
, V_입고수량 TBL_입고.입고수량%TYPE
, V_입고단가 TBL_입고.입고단가%TYPE
)
IS
-- 선언부
-- 아래의 쿼리문을 수행하기 위해 필요한 변수 추가 선언
V_입고번호 TBL_입고.입고번호%TYPE;
BEGIN
-- 실행부
-- 선언한 변수에 값 담아내기
-- SELECT 쿼리문 수행 → 입고번호 확인
SELECT NVL(MAX(입고번호), 0) INTO V_입고번호
FROM TBL_입고;
-- 레코드가 있는 상태에서...
SELECT MAX(NVL(입고번호, 1))
FROM TBL_입고;
--==>> (NULL)
--**************************************************************************
-- 레코드 자체가 없는 데에서 가져오니까
-- NULL이 반환이 안 되는 것이다.
-- 만약 레코드가 존재하는데, 입고번호가 NULL이었다면 NVL이 제대로 실행되었겠지만
-- 현재 레코드가 존재하지 않는 상태이므로...
--**************************************************************************
-- INSERT 쿼리문 수행
INSERT INTO TBL_입고 (입고번호, 상품코드, 입고수량, 입고단가)
VALUES ((V_입고번호 + 1), V_상품코드, V_입고수량, V_입고단가);
-- UPDATE 쿼리문 수행
-- 논리적으로, 입고수량 테이블에 레코드가 추가되어야 UPDATE TBL_상품 을 할 수 있으므로
-- INSERT INTO 이후에 UPDATE를 한 것이다.
UPDATE TBL_상품
SET 재고수량 = 재고수량 + V_입고수량
WHERE 상품코드 = V_상품코드;
-- 커밋
-- 예외 처리
EXCEPTION
-- 코드레벨에서 명시한 상황이 아닌 다른 상황이 발생하게 되면...
-- THEN 롤백해라!!
WHEN OTHERS THEN ROLLBACK;
-- 기존 상황이 아닌 상황이 발생했을 경우 모두 ROLLBACK!
-- 그 어떠한 것도 반영하지 않는다.
COMMIT;
END;
--==>> Procedure PRC_입고_INSERT2이(가) 컴파일되었습니다.
--------------------------------------------------------------------------------
--★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
--★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
--★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
--★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
-- ★ [이 문제를 통해 선생님이 전달하고 싶었던 것...]
/*
혜성 윤수
농협 신한
1,200,000 → 200,000 0
1,000,000 (데이트비 하라구 100만 원 빌려줌...)
UPDATE 고객계좌 UPDATE 고객계좌
SET 잔액 = 200000 SET 잔액 = 1000000
WHERE 예금주코드 = 혜성 WHERE 예금주코드 = 윤수
만약, 혜성이가 100만 원을 입금할 때 전산장애가 발생해서
윤수한테 100만 원이 전해지지 않고, 혜성이는 20만 원만 남는다?
둘 중에 하나만 실행된다면 위와 같은 문제가 발생할 것이다.
하지만, 트랜잭션은 한번에 실행 되거나 실행되지 않거나 둘 중 하나이기 때문에
(ALL OR NOTHING)!!!!!!!!!!!!!
트랜잭션의 특징
ⓐ 【원자성(ATOMICITY)】
트랜잭션에서 정의된 연산들은
모두 성공하거나, 모두 실행되지 않거나 둘 중 하나이다.
ALL OR NOTHING!!!!!!!!!!!!!!!
둘 중에 어느 하나라도 문제가 생기면 ROLLBACK을 한다!!
그렇기에 위와 같은 문제가 발생하지 않는다.
혜성 = 빨강 동그라미
윤수 = 파랑 동그라미
빨강 동그라미, 파랑 동그라미가 모두 성공했을 때 = COMMIT!
둘 중 하나라도 실패 = ROLLBACK!
★이러한 처리를 [트랜잭션 처리]라고 한다.
일부만 실행 : 롤백
모두 실행 완료 : COMMIT!!
TCL 구문(TRANSACTION CONTROL LANGUAGE) : COMMIT, ROLLBACK!!!
입고수량 입력을 했는데 재고수량이 변경되지 않으면 = 무결성이 깨진다!!
두 개가 모두 실행됐을 때 커밋이 되어야 한다.
둘 중에 하나만 실행 됐을 때는 커밋 금지!!!
둘 중에 하나만 실행 됐을 때 ROLLBACK!!!!
*/
--------------------------------------------------------------------------------
--■■■ 프로시저 내에서의 예외 처리 ■■■--
--○ TBL_MEMBER 테이블에 데이터를 입력하는 프로시저를 작성
-- 단, 이 프로시저를 통해 데이터를 입력할 경우
-- CITY(지역) 항목에 '서울', '경기', '대전'만 입력이 가능하도록 구성한다.
-- 이 지역 외의 다른 지역을 프로시저 호출을 통해 입력하려는 경우
-- (즉, 유효하지 않은 데이터 입력을 시도하려는 경우)
-- 예외에 대한 처리를 하려고 한다.
-- 프로시저명 : PRC_MEMBER_INSERT()
/*
실행 예)
EXEC PRC_MEMBER_INSERT('박범구', '010-1111-1111', '서울');
--> 데이터 입력 ○
EXEC PRC_MEMBER_INSERT('김경태', '010-2222-2222', '부산');
--> 데이터 입력 Ⅹ
*/
CREATE OR REPLACE PROCEDURE PRC_MEMBER_INSERT
( V_NAME IN TBL_MEMBER.NAME%TYPE
, V_TEL IN TBL_MEMBER.TEL%TYPE
, V_CITY IN TBL_MEMBER.CITY%TYPE
)
IS
-- 실행 영역의 쿼리문 수행을 위해 필요한 변수 선언
V_NUM TBL_MEMBER.NUM%TYPE;
-- 사용자 정의 예외를 변수처럼 선언하여, IF문에서 처리하자.
-- USER_DEFINE_ERROR는 '예외타입'이다.
-- 사용자 정의 예외에 대한 변수 선언 CHECK~!!!
USER_DEFINE_ERROR EXCEPTION;
BEGIN
-- 프로시저를 통해 입력 처리를 정상적으로 진행해야 할 데이터인지 아닌지의 여부를
-- 가장 먼저 확인할 수 있도록 코드 구성
-- 매개변수로 입력받은 값이, 서울, 경기, 대전 중 어느 하나도 아닐 경우.
IF (V_CITY NOT IN ('서울', '경기', '대전'))
-- 예외 발생 CHECK~!!!
-- *[RAISE] : 일으키다, 발생시키다.
-- 서울, 경기, 대전이 아닐 경우 USER_DEFINE_ERROR를 발생시킬 것이다.
-- 예외를 일으키는 구문은 항상 COMMIT보다 먼저 작성하자.
THEN RAISE USER_DEFINE_ERROR;
END IF;
-- 선언한 변수에 값 담아내기
SELECT NVL(MAX(NUM), 0) INTO V_NUM
FROM TBL_MEMBER;
-- 쿼리문 구성 → INSERT
INSERT INTO TBL_MEMBER(NUM, NAME, TEL, CITY)
VALUES(V_NUM + 1, V_NAME, V_TEL, V_CITY);
-- 예외 처리 구문
-- 오류가, USER_DEFINE_ERROR라면...
-- 오라클 내장 에러 함수를 호출한다.
-- 2만 1번부터 유저가 부여할 수 있는 에러 번호이다.
-- [JAVA]의 TRY~CATCH 와 유사함.
EXCEPTION
WHEN USER_DEFINE_ERROR
THEN RAISE_APPLICATION_ERROR(-20001, '서울, 경기, 대전만 입력이 가능합니다.');
ROLLBACK;
-- 잘못된 데이터를 입력했으므로, 롤백한다!
-- 우리가 규정한 에러 : USER_DEFINE_ERROR가 아닌 것이 발생할 수도 있다!
-- 기타 다른 예외가 발생하면...
WHEN OTHERS
THEN ROLLBACK; -- 롤백만 해라~!!
-- 사용자 정의 예외를 여러 개 지정해서
-- 각 에러의 경우에 따라 다른 안내 메시지가 출력되도록 처리할 수도 있겠다.
-- 커밋
COMMIT;
END;
--==>> Procedure PRC_MEMBER_INSERT이(가) 컴파일되었습니다.
DESC TBL_출고;
--○ TBL_출고 테이블에 데이터 입력 시 (즉, 출고 이벤트 발생 시)
-- TBL_상품 테이블의 재고수량이 변동되는 프로시저를 작성한다.
-- 단, 출고번호는 입고번호와 마찬가지로 자동 증가,
-- 또한, 출고수량이 재고수량보다 많은 경우...
-- 출고 액션을 취소할 수 있도록 처리한다.
-- (출고가 이루어지지 않도록...) → 예외 처리 활용 CHECK~!!!
-- 프로시저명 : PRC_출고_INSERT()
/*
실행 예)
EXEC PRC_출고_INSERT('H001', 10, 600);
→ 이 시점에서의 상품 테이블의 바밤바 재고수량은 70개
EXEC PRC_출고_INSERT('H001', 80, 600);
→ 에러 발생
-- (20002, 재고 부족~!!!)
*/
/*
이름 널? 유형
---- -------- ------------
출고번호 NOT NULL NUMBER
상품코드 VARCHAR2(20)
출고일자 DATE
출고수량 NUMBER
출고단가 NUMBER
*/
CREATE OR REPLACE PROCEDURE PRC_출고_INSERT
( V_상품코드 IN TBL_출고.상품코드%TYPE
, V_출고수량 IN TBL_출고.출고수량%TYPE
, V_출고단가 IN TBL_출고.출고단가%TYPE
)
IS
V_출고번호 TBL_출고.출고번호%TYPE;
V_재고수량 TBL_상품.재고수량%TYPE;
USER_DEFINE_ERROR2 EXCEPTION;
BEGIN
-- #1 출고번호 연산
SELECT NVL(MAX(출고번호), 0) + 1 INTO V_출고번호
FROM TBL_출고;
-- #2 TBL_출고 테이블에 입력.
INSERT INTO TBL_출고(출고번호, 상품코드, 출고수량, 출고단가)
VALUES(V_출고번호, V_상품코드, V_출고수량, V_출고단가);
SELECT 재고수량 INTO V_재고수량
FROM TBL_상품
WHERE 상품코드 = V_상품코드;
-- #5 EXCEPTION 정의
-- 입력받은 출고수량이, 상품의 재고수량보다 클 때 EXCEPTION 발생
IF (V_출고수량 > V_재고수량)
THEN RAISE USER_DEFINE_ERROR2;
END IF;
-- #3 출고 테이블의 수량과 상품코드에 맞게 수량을 제거.
UPDATE TBL_상품
SET 재고수량 = 재고수량 - V_출고수량
WHERE 상품코드 = V_상품코드;
EXCEPTION
WHEN USER_DEFINE_ERROR2
THEN RAISE_APPLICATION_ERROR(-20002, '재고 부족~!!!');
ROLLBACK;
WHEN OTHERS
THEN ROLLBACK;
-- #4 커밋
COMMIT;
END;
--[선생님 풀이!!!]
CREATE OR REPLACE PROCEDURE PRC_출고_INSERT2
( V_상품코드 IN TBL_상품.상품코드%TYPE
, V_출고수량 IN TBL_출고.출고수량%TYPE
, V_출고단가 IN TBL_출고.출고단가%TYPE
)
IS
-- 주요 변수 선언
V_출고번호 TBL_출고.출고번호%TYPE;
V_재고수량 TBL_상품.재고수량%TYPE;
-- 사용자 정의 예외 선언
USER_DEFINE_ERROR EXCEPTION;
BEGIN
-- 쿼리문 수행 이전에 수행 여부를 확인하는 과정에서
-- 재고수량 파악 → 기존 재고를 확인하는 과정이 선행되어야 한다.
-- 그래야 프로시저 호출 시 넘겨받는 출고수량과 비교가 가능하기 때문...
SELECT 재고수량 INTO V_재고수량
FROM TBL_상품
WHERE 상품코드 = V_상품코드;
-- 출고를 정상적으로 진행해줄 것인지에 대한 여부 확인
-- 위에서 파악한 재고수량보다 현재 프로시저에서 넘겨받은 출고수량이 많으면
-- 예외 발생~!!!
IF (V_출고수량 > V_재고수량)
-- 예외 발생
THEN RAISE USER_DEFINE_ERROR;
END IF;
-- 출고번호 얻어내기 → 위에서 선언한 변수에 값 담아내기
SELECT NVL(MAX(출고번호), 0) + 1 INTO V_출고번호
FROM TBL_출고;
-- 쿼리문 구성 → INSERT(TBL_출고)
INSERT INTO TBL_출고(출고번호, 상품코드, 출고수량, 출고단가)
VALUES(V_출고번호, V_상품코드, V_출고수량, V_출고단가);
-- 쿼리문 구성 → UPDATE(TBL_상품)
UPDATE TBL_상품
SET 재고수량 = 재고수량 - V_출고수량
WHERE 상품코드 = V_상품코드;
-- 항상 예외 처리는 커밋 위에서 수행하기로 하자.
-- JAVA에서의 TRY~CATCH처럼 처리하자.
--예외 처리
EXCEPTION
WHEN USER_DEFINE_ERROR
THEN RAISE_APPLICATION_ERROR(-20002, '재고 부족~!!!');
ROLLBACK;
WHEN OTHERS
THEN ROLLBACK;
-- 커밋
COMMIT;
END;
--==>> Procedure PRC_출고_INSERT2이(가) 컴파일되었습니다.
-- EXCEPTION 변수 선언 (USER_DEFINE_ERROR2)
-- IF (예외처리할 상황이 되면)
-- THEN RAISE (EXCEPTION 변수명)
-- END IF;
-- EXCEPTION 이 발생했을 때 할 처리.
-- EXCEPTION
-- WHEN (사용자정의 EXCEPTION?)
-- THEN RAISE_APPLICATION_ERROR(에러번호(20000부터...), '안내메시지');
--○ TBL_출고 테이블에서 출고수량을 수정(변경)하는 프로시저를 작성한다.
-- 프로시저명 : PRC_출고_UPDATE()
/*
실행 예)
EXEC PRC_출고_UPDATE(출고번호, 변경할수량);
*/
-- 잘못 들어갔던 출고수량을 다시 더해주고, 그 결과값에서 변경할 수량을 빼 준다.
-- 20 -> 50 가능
-- 20 -> 60 불가능(재고수량초과)
--********************************************************************
-- ① 잘못 들어갔던 출고 수량을 상품의 재고 수량에 더해준다.
-- ② 그 수량이 현재의 변경할 수량보다 작거나 같으면 : 변경 가능하다.
-- 크면 : 변경이 불가능하다!!!!
--********************************************************************
DESC TBL_출고;
DESC TBL_상품;
CREATE OR REPLACE PROCEDURE PRC_출고_UPDATE
( V_출고번호 IN TBL_출고.출고번호%TYPE
, V_변경할수량 IN TBL_출고.출고수량%TYPE
)
IS
-- # 출고번호에 맞는 상품 번호 저장
V_상품코드 TBL_상품.상품코드%TYPE;
-- # 변경하려는 출고 번호에 맞는 출고수량을 저장.
V_변경전출고수량 TBL_출고.출고수량%TYPE;
-- # 상품 번호에 맞는 재고수량 저장
V_재고수량 TBL_상품.재고수량%TYPE;
-- # 이전 출고수량을 다시 되돌려서
-- 원래의 재고수량에 더했을 때의 값을 저장할 변수 지정.
V_취소후재고수량 TBL_상품.재고수량%TYPE;
-- # 사용자 정의 에러(EXCEPTION 정의)
USER_DEFINE_ERROR3 EXCEPTION;
BEGIN
-- #1 출고번호의 상품 코드를 확인.
-- 그 값을 변수에 저장.
SELECT 상품코드 INTO V_상품코드
FROM TBL_출고
WHERE 출고번호 = V_출고번호;
-- #2 출고번호에 맞는 변경전 출고 수량을 변수에 저장.
SELECT 출고수량 INTO V_변경전출고수량
FROM TBL_출고
WHERE 출고번호 = V_출고번호;
-- #3 출고번호의 상품 코드와 일치하는 상품의 재고수량 확인
SELECT 재고수량 INTO V_재고수량
FROM TBL_상품
WHERE 상품코드 = V_상품코드;
--50 LINE
-- #4 잘못 들어갔던 출고수량을 다시 더해준다.
V_취소후재고수량 := V_재고수량 + V_변경전출고수량;
-- #5 사용자가 매개변수로 입력한 V_변경할수량이
-- 위에서 연산한 취소후 재고수량보다 클 경우 에러를 발생시킨다.
IF (V_변경할수량 > V_취소후재고수량)
THEN RAISE USER_DEFINE_ERROR3;
END IF;
-- #5-1 EXCEPTION 이 발생하지 않았을 경우, 제대로 연산을 진행한다.
-- ① 출고번호에 맞는 TBL_출고 테이블의 레코드를 변경할 수량에 맞게 업데이트한다.
UPDATE TBL_출고
SET 출고수량 = V_변경할수량
WHERE 출고번호 = V_출고번호;
-- ② 출고번호에 맞는 상품코드를 TBL_상품 테이블에서 조회하여
-- 재고를 취소한 수량만큼 증가시킨다.
UPDATE TBL_상품
SET 재고수량 = V_취소후재고수량 - V_변경할수량
WHERE 상품코드 = V_상품코드;
-- ③ 그 결과에서 V_변경할수량 만큼 감소시킨다.
-- ④ ③의 값을 기반으로, TBL_상품의 테이블을 업데이트한다.
-- #6 EXCEPTION 에 대한 처리를 진행한다.
EXCEPTION
WHEN USER_DEFINE_ERROR3
THEN RAISE_APPLICATION_ERROR(-20003, '재고 부족~!!!');
ROLLBACK;
WHEN OTHERS
THEN
ROLLBACK;
-- 모든 처리가 끝난 후에 COMMIT을 진행한다.
COMMIT;
END;
20231106_02_scott.sql
SELECT USER
FROM DUAL;
--==>> SCOTT
--○ 프로시저 생성 후 실행 테스트 (잘못된 패스워드)
EXEC PRC_STUDENT_UPDATE2('moon', 'java000', '010-9999-9999', '강원도 횡성');
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
--○프로시저 호출 후 테이블 조회
SELECT *
FROM TBL_STUDENTS;
--==>>
/*
ID NAME TEL ADDR
moon 문정환 010-1111-1111 제주도 서귀포시 --> 데이터 변경되지 않았음~!!!
wool 정한울 010-2222-2222 서울 강남구
*/
--○ 프로시저 생성 후 실행 테스트 (올바른 패스워드)
EXEC PRC_STUDENT_UPDATE2('moon', 'java006$', '010-9999-9999', '강원도 횡성');
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
--○프로시저 호출 후 테이블 조회
SELECT *
FROM TBL_STUDENTS;
--==>>
/*
ID NAME TEL ADDR
moon 문정환 010-9999-9999 강원도 횡성
wool 정한울 010-2222-2222 서울 강남구
*/
--○ 프로시저 생성 후 실행 테스트 (잘못된 패스워드)
EXEC PRC_STUDENT_UPDATE2('wool', 'java000', '010-8888-8888', '전남 목포');
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
--○프로시저 호출 후 테이블 조회
SELECT *
FROM TBL_STUDENTS;
--==>>
/*
ID NAME TEL ADDR
moon 문정환 010-9999-9999 강원도 횡성
wool 정한울 010-2222-2222 서울 강남구
*/
--○ 프로시저 생성 후 실행 테스트 (올바른 패스워드)
EXEC PRC_STUDENT_UPDATE2('wool', 'java006$', '010-8888-8888', '전남 목포');
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
--○프로시저 호출 후 테이블 조회
SELECT *
FROM TBL_STUDENTS;
--==>>
/*
ID NAME TEL ADDR
moon 문정환 010-9999-9999 강원도 횡성
wool 정한울 010-8888-8888 전남 목포
*/
DESC TBL_INSA;
--==>>
/*
이름 널? 유형
-------- -------- ------------
NUM NOT NULL NUMBER(5)
NAME NOT NULL VARCHAR2(20)
SSN NOT NULL VARCHAR2(14)
IBSADATE NOT NULL DATE
CITY VARCHAR2(10)
TEL VARCHAR2(15)
BUSEO NOT NULL VARCHAR2(15)
JIKWI NOT NULL VARCHAR2(15)
BASICPAY NOT NULL NUMBER(10)
SUDANG NOT NULL NUMBER(10)
*/
SELECT *
FROM TBL_INSA;
EXEC PRC_INSA_INSERT('최혜인', '970812-2234567', SYSDATE, '서울', '010-2509-1783', '개발부', '대리', 2000000, 2000000);
SELECT *
FROM TBL_INSA;
-- [선생님 프로시저!!!]
--※ 20231106_01_scott(plsql).sql 파일에서
-- PRC_INSA_INSERT() 프로시저 생성 후 테스트
-- 프로시저는 개행해서 실행하지 않는다. 한 줄로 실행하자!!
EXEC PRC_INSA_INSERT2('최혜인', '970812-2234567', SYSDATE, '서울', '010-2509-1783', '개발부', '대리', 2000000, 2000000);
--==> PL/SQL 프로시저가 성공적으로 완료되었습니다.
--○ 프로시저 호출(실행) 후 확인
SELECT *
FROM TBL_INSA;
--○ 실습 테이블 생성(TBL_상품)
CREATE TABLE TBL_상품
( 상품코드 VARCHAR2(20)
, 상품명 VARCHAR2(100)
, 소비자가격 NUMBER
, 재고수량 NUMBER DEFAULT 0
, CONSTRAINT 상품_상품코드_PK PRIMARY KEY(상품코드)
);
--==>> Table TBL_상품이(가) 생성되었습니다.
-- TBL_상품 테이블의 상품코드 기본키(PK) 제약조건 설정
--○ 실습 테이블 생성(TBL_입고)
CREATE TABLE TBL_입고
( 입고번호 NUMBER
, 상품코드 VARCHAR2(20)
, 입고일자 DATE DEFAULT SYSDATE
, 입고수량 NUMBER
, 입고단가 NUMBER
, CONSTRAINT 입고_입고번호_PK PRIMARY KEY (입고번호)
, CONSTRAINT 입고_상품코드_FK FOREIGN KEY (상품코드)
REFERENCES TBL_상품(상품코드)
);
--==>> Table TBL_입고이(가) 생성되었습니다.
-- TBL_입고 테이블의 입고번호를 기본키(PK) 제약조건 설정
-- TBL_입고 테이블의 상품코드는 TBL_상품 테이블의 상품코드를
-- 참조할수 있도록 외래키(FK) 제약조건 설정
--○ TBL_상품 테이블에 상품정보 입력
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('H001', '바밤바', 600);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('H002', '죠스바', 500);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('H003', '보석바', 500);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('H004', '누가바', 600);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('H005', '쌍쌍바', 700);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('H006', '수박바', 500);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('H007', '알껌바', 500);
--==>> 1 행 이(가) 삽입되었습니다. * 7
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('C001', '빵빠레', 1600);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('C002', '월드콘', 1500);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('C003', '메타콘', 1500);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('C004', '구구콘', 1600);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('C005', '슈퍼콘', 1700);
--==>> 1 행 이(가) 삽입되었습니다. * 5
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('E001', '빵또아', 2600);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('E002', '투게더', 2500);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('E003', '팥빙수', 2500);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('E004', '셀렉션', 2600);
INSERT INTO TBL_상품(상품코드, 상품명, 소비자가격) VALUES('E005', '설레임', 2700);
--○ 확인
SELECT *
FROM TBL_상품;
--==>>
/*
상품코드 상품명 소비자가격 재고수량
H001 바밤바 600 0
H002 죠스바 500 0
H003 보석바 500 0
H004 누가바 600 0
H005 쌍쌍바 700 0
H006 수박바 500 0
H007 알껌바 500 0
C001 빵빠레 1600 0
C002 월드콘 1500 0
C003 메타콘 1500 0
C004 구구콘 1600 0
C005 슈퍼콘 1700 0
E001 빵또아 2600 0
E002 투게더 2500 0
E003 팥빙수 2500 0
E004 셀렉션 2600 0
E005 설레임 2700 0
*/
--○ 커밋
COMMIT;
--==>> 커밋 완료
--○ 테이블 조회(입고내역 확인)
SELECT *
FROM TBL_입고;
--==>> 조회 결과 없음
--※ TBL_입고 테이블에 『입고』 이벤트 발생 시...
-- 관련 테이블에 수행되어야 하는 내용
-- ① INSERT → TBL_입고
-- INSERT INTO TBL_입고(입고번호, 상품코드, 입고일자, 입고수량, 입고단가)
-- VALUES(1, 'H001', SYSDATE, 30, 400);
-- ② UPDATE → TBL_상품
-- UPDATE TBL_상품
-- SET 재고수량 = 기존재고수량 + 입고수량 -- CHECK~!!!
-- WHERE 상품코드 = 'H001';
-- 프로시저명 : PRC_입고_INSERT(상품코드, 입고수량, 입고단가)
EXEC PRC_입고_INSERT('H001', 20, 400);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
SELECT *
FROM TBL_상품;
--○ 생성한 프로시저가 제대로 작동하는지의 여부 확인 → 프로시저 호출
EXEC PRC_입고_INSERT(상품코드, 입고수량, 입고단가);
SELECT *
FROM TBL_입고;
EXEC PRC_입고_INSERT('H001', 30, 500);
SELECT *
FROM TBL_상품;
--==>>
/*
:
H001 바밤바 600 30
:
*/
SELECT *
FROM TBL_입고;
--==>>
/*
입고번호 상품코드 입고일자 입고수량 입고단가
1 H001 2023-11-06 30 500
*/
EXEC PRC_입고_INSERT('H002', 20, 400);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
SELECT *
FROM TBL_상품;
--==>>
/*
:
H002 죠스바 500 20
:
*/
SELECT *
FROM TBL_입고;
--==>>
/*
입고번호 상품코드 입고일자 입고수량 입고단가
1 H001 2023-11-06 30 500
2 H002 2023-11-06 20 400
*/
EXEC PRC_입고_INSERT('H001', 50, 500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
SELECT *
FROM TBL_상품;
--==>>
/*
H001 바밤바 600 80
*/
SELECT *
FROM TBL_입고;
--==>>
/*
입고번호 상품코드 입고일자 입고수량 입고단가
3 H001 2023-11-06 50 500
1 H001 2023-11-06 30 500
2 H002 2023-11-06 20 400
*/
EXEC PRC_입고_INSERT('H002', 30, 400);
EXEC PRC_입고_INSERT('H003', 35, 400);
EXEC PRC_입고_INSERT('H004', 70, 500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다. * 3
EXEC PRC_입고_INSERT('C001', 26, 1400);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_입고_INSERT('C001', 24, 1400);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_입고_INSERT('C001', 20, 1500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_입고_INSERT('C002', 20, 1000);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_입고_INSERT('C003', 20, 1000);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_입고_INSERT('C004', 20, 1000);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
SELECT *
FROM TBL_입고;
--==>>
/*
입고번호 상품코드 입고일자 입고수량 입고단가
3 H001 2023-11-06 50 500
4 H002 2023-11-06 30 400
1 H001 2023-11-06 30 500
2 H002 2023-11-06 20 400
5 H003 2023-11-06 35 400
6 H004 2023-11-06 70 500
7 C001 2023-11-06 26 1400
8 C001 2023-11-06 24 1400
9 C001 2023-11-06 20 1500
10 C002 2023-11-06 20 1000
11 C003 2023-11-06 20 1000
12 C004 2023-11-06 20 1000
*/
SELECT *
FROM TBL_상품;
--==>>
/*
상품코드 상품명 소비자가격 재고수량
H001 바밤바 600 80
H002 죠스바 500 50
H003 보석바 500 35
H004 누가바 600 70
H005 쌍쌍바 700 0
H006 수박바 500 0
H007 알껌바 500 0
C001 빵빠레 1600 70
C002 월드콘 1500 20
C003 메타콘 1500 20
C004 구구콘 1600 20
C005 슈퍼콘 1700 0
E001 빵또아 2600 0
E002 투게더 2500 0
E003 팥빙수 2500 0
E004 셀렉션 2600 0
E005 설레임 2700 .0
*/
--------------------------------------------------------------------------------
--■■■ 프로시저 내에서의 예외 처리 ■■■--
--○ 실습 테이블 생성(TBL_MEMBER)
CREATE TABLE TBL_MEMBER
( NUM NUMBER
, NAME VARCHAR2(30)
, TEL VARCHAR2(60)
, CITY VARCHAR2(60)
, CONSTRAINT MEMBER_NUM_PK PRIMARY KEY (NUM)
);
--==>> Table TBL_MEMBER이(가) 생성되었습니다.
-- CITY에 입력할 수 있는 데이터는,
-- 경기, 대전과 같은 특정 값만 입력이 가능하도록 하려고 하는 것.
--○ 생성한 프로시저가 제대로 작동하는지의 여부 확인
EXEC PRC_MEMBER_INSERT('박범구', '010-1111-1111', '서울');
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
SELECT *
FROM TBL_MEMBER;
--==>>
/*
NUM NAME TEL CITY
1 박범구 010-1111-1111 서울
*/
EXEC PRC_MEMBER_INSERT('김경태', '010-2222-2222', '부산');
--==>> 에러 발생
-- ORA-20001 (아까 전에 사용자가 부여했던 에러 번호)
/*
명령의 448 행에서 시작하는 중 오류 발생 -
BEGIN PRC_MEMBER_INSERT('김경태', '010-2222-2222', '부산'); END;
오류 보고 -
ORA-20001: 서울, 경기, 대전만 입력이 가능합니다.
ORA-06512: at "SCOTT.PRC_MEMBER_INSERT", line 53
ORA-06512: at line 1
*/
SELECT *
FROM TBL_MEMBER;
--==>> 1 박범구 010-1111-1111 서울
DESC TBL_상품;
--○ 실습 테이블 생성(TBL_출고)
CREATE TABLE TBL_출고
( 출고번호 NUMBER
, 상품코드 VARCHAR2(20)
, 출고일자 DATE DEFAULT SYSDATE
, 출고수량 NUMBER
, 출고단가 NUMBER
);
--==>> Table TBL_출고이(가) 생성되었습니다.
-- 출고번호 PK 지정
ALTER TABLE TBL_출고
ADD CONSTRAINT 출고_출고번호_PK PRIMARY KEY (출고번호);
--==>> Table TBL_출고이(가) 변경되었습니다.
SELECT *
FROM TBL_상품;
SELECT *
FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'TBL_상품';
-- 상품코드 FK 지정
ALTER TABLE TBL_출고
ADD CONSTRAINT 출고_상품코드_FK FOREIGN KEY (상품코드)
REFERENCES TBL_상품(상품코드);
--==>> Table TBL_출고이(가) 변경되었습니다.
--------------------------------------------------------------------------------
SELECT *
FROM TBL_상품;
--==>>
/*
상품코드 상품명 소비자가격 재고수량
H001 바밤바 600 80
H002 죠스바 500 50
H003 보석바 500 35
H004 누가바 600 70
H005 쌍쌍바 700 0
H006 수박바 500 0
H007 알껌바 500 0
C001 빵빠레 1600 70
C002 월드콘 1500 20
C003 메타콘 1500 20
C004 구구콘 1600 20
C005 슈퍼콘 1700 0
E001 빵또아 2600 0
E002 투게더 2500 0
E003 팥빙수 2500 0
E004 셀렉션 2600 0
E005 설레임 2700 0
*/
SELECT *
FROM TBL_입고;
--==>>
/*
입고번호 상품코드 입고일자 입고수량 입고단가
3 H001 2023-11-06 50 500
4 H002 2023-11-06 30 400
1 H001 2023-11-06 30 500
2 H002 2023-11-06 20 400
5 H003 2023-11-06 35 400
6 H004 2023-11-06 70 500
7 C001 2023-11-06 26 1400
8 C001 2023-11-06 24 1400
9 C001 2023-11-06 20 1500
10 C002 2023-11-06 20 1000
11 C003 2023-11-06 20 1000
12 C004 2023-11-06 20 1000
*/
SELECT *
FROM TBL_출고;
--==>> 조회 결과 없음
EXEC PRC_출고_INSERT('H001', 10, 600);
SELECT *
FROM TBL_출고;
SELECT *
FROM TBL_상품;
EXEC PRC_출고_INSERT('H001', 80, 600);
--○ 생성한 프로시저가 제대로 작동하는지의 여부 확인
-- 현재 상품 테이블의 바밤바 재고 수량은 70개
-- 프로시저의 호출 의미는 바밤바 10개 출고
EXEC PRC_출고_INSERT2('H001', 10, 600);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
SELECT *
FROM TBL_상품;
--==>>
/*
상품코드 상품명 소비자가격 재고수량
H001 바밤바 600 60
H002 죠스바 500 50
H003 보석바 500 35
H004 누가바 600 70
H005 쌍쌍바 700 0
H006 수박바 500 0
H007 알껌바 500 0
C001 빵빠레 1600 70
C002 월드콘 1500 20
C003 메타콘 1500 20
C004 구구콘 1600 20
C005 슈퍼콘 1700 0
E001 빵또아 2600 0
E002 투게더 2500 0
E003 팥빙수 2500 0
E004 셀렉션 2600 0
E005 설레임 2700 0
*/
EXEC PRC_출고_INSERT2('C001', 20, 1500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_출고_INSERT2('C001', 20, 1500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_출고_INSERT2('C001', 10, 1500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_출고_INSERT2('C001', 30, 1500);
--==>> 에러 발생
-- (ORA-20002: 재고 부족~!!!)
SELECT *
FROM TBL_상품;
--==>>
/*
H001 바밤바 600 60
H002 죠스바 500 50
H003 보석바 500 35
H004 누가바 600 70
H005 쌍쌍바 700 0
H006 수박바 500 0
H007 알껌바 500 0
C001 빵빠레 1600 20
C002 월드콘 1500 20
C003 메타콘 1500 20
C004 구구콘 1600 20
C005 슈퍼콘 1700 0
E001 빵또아 2600 0
E002 투게더 2500 0
E003 팥빙수 2500 0
E004 셀렉션 2600 0
E005 설레임 2700 0
*/
EXEC PRC_출고_INSERT2('H001', 10, 500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_출고_INSERT2('H001', 10, 500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_출고_INSERT2('H001', 10, 500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
SELECT *
FROM TBL_상품;
EXEC PRC_출고_INSERT2('H002', 20, 500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
EXEC PRC_출고_INSERT2('H003', 15, 500);
--==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
--------------------------------------------------------------------------------
SELECT *
FROM TBL_상품;
--==>>
/*
상품코드 상품명 소비자가격 재고수량
H001 바밤바 600 30
H002 죠스바 500 30
H003 보석바 500 20
H004 누가바 600 70
H005 쌍쌍바 700 0
H006 수박바 500 0
H007 알껌바 500 0
C001 빵빠레 1600 20
C002 월드콘 1500 20
C003 메타콘 1500 20
C004 구구콘 1600 20
C005 슈퍼콘 1700 0
E001 빵또아 2600 0
E002 투게더 2500 0
E003 팥빙수 2500 0
E004 셀렉션 2600 0
E005 설레임 2700 0
*/
SELECT *
FROM TBL_출고;
--==>>
/*
출고번호 상품코드 출고일자 출고수량 출고단가
2 H001 2023-11-06 10 600
1 H001 2023-11-06 10 600
3 C001 2023-11-06 20 1500
4 C001 2023-11-06 20 1500
5 C001 2023-11-06 10 1500
6 H001 2023-11-06 10 500
7 H001 2023-11-06 10 500
8 H001 2023-11-06 10 500
9 H002 2023-11-06 20 500
10 H003 2023-11-06 15 500
*/
EXEC PRC_출고_UPDATE(1, 15);
EXEC PRC_출고_UPDATE(1, 43);
'[Oracle] > PL·SQL (Program source)' 카테고리의 다른 글
[Oracle - PL/SQL] 20231108 [프로그램 소스] (0) | 2023.11.09 |
---|---|
[Oracle - PL/SQL] 20231107 [프로그램 소스] (2) | 2023.11.07 |
[Oracle - PL/SQL] 20231103 [프로그램 소스] (0) | 2023.11.03 |
[Oracle - PL/SQL] 20231102 [프로그램 소스] (0) | 2023.11.03 |