(1)고객(CUSTOMER)
고객번호(CUST_NO/PK), 고객명(CUST_NAME)
(2)사원(EMPLOYEE)
사원번호(EMP_NO/PK), 부서(DEPT), 호봉(SALEGRADE)
(3)예산(BUDGET)
부서(DEPT_NO/PK1), 계정과목(ACCOUNT/PK2), 예산년도(BUDGET_YR/PK3), 편성금액(BUDGET_AMT)
SQL>
CREATE TABLE ORA9.CUSTOMER (
2 CUST_NO VARCHAR2(4) NOT NULL
3 , CUST_NAME VARCHAR2(10) NOT NULL
4 )
5 TABLESPACE ORA9;
테이블이 생성되었습니다.
SQL>
COMMENT ON TABLE ORA9.CUSTOMER IS '고객';
주석이 생성되었습니다.
SQL>
COMMENT ON COLUMN ORA9.CUSTOMER.CUST_NO IS '고객번호';
주석이 생성되었습니다.
SQL>
COMMENT ON COLUMN ORA9.CUSTOMER.CUST_NAME IS '고객명';
주석이 생성되었습니다.
SQL>
ALTER TABLE ORA9.CUSTOMER ADD (
2 CONSTRAINT CUSTOMER_PK PRIMARY KEY ( CUST_NO )
3 USING INDEX TABLESPACE ORA9 );
테이블이 변경되었습니다.
SQL>
CREATE TABLE ORA9.EMPLOYEE (
2 EMP_NO VARCHAR2(4) NOT NULL
3 , DEPT VARCHAR2(10) NOT NULL
4 , SALEGRADE VARCHAR2(2) NOT NULL
5 )
6 TABLESPACE ORA9;
테이블이 생성되었습니다.
SQL>
COMMENT ON TABLE ORA9.EMPLOYEE IS '사원';
주석이 생성되었습니다.
SQL>
COMMENT ON COLUMN ORA9.EMPLOYEE.EMP_NO IS '사원번호';
주석이 생성되었습니다.
SQL>
COMMENT ON COLUMN ORA9.EMPLOYEE.DEPT IS '부서';
주석이 생성되었습니다.
SQL>
COMMENT ON COLUMN ORA9.EMPLOYEE.SALEGRADE IS '호봉';
주석이 생성되었습니다.
SQL>
ALTER TABLE ORA9.EMPLOYEE ADD (
2 CONSTRAINT EMPLOYEE_PK PRIMARY KEY ( EMP_NO )
3 USING INDEX TABLESPACE ORA9 );
테이블이 변경되었습니다.
SQL>
CREATE TABLE ORA9.BUDGET (
2 DEPT_NO VARCHAR2(4) NOT NULL
3 , ACCOUNT VARCHAR2(4) NOT NULL
4 , BUDGET_YR VARCHAR2(4) NOT NULL
5 , BUDGET_AMT NUMBER(10) NOT NULL
6 )
7 TABLESPACE ORA9;
테이블이 생성되었습니다.
SQL>
COMMENT ON TABLE ORA9.BUDGET IS '예산';
주석이 생성되었습니다.
SQL>
COMMENT ON COLUMN ORA9.BUDGET.DEPT_NO IS '부서';
주석이 생성되었습니다.
SQL>
COMMENT ON COLUMN ORA9.BUDGET.ACCOUNT IS '계정과목';
주석이 생성되었습니다.
SQL>
COMMENT ON COLUMN ORA9.BUDGET.BUDGET_YR IS '예산년도';
주석이 생성되었습니다.
SQL>
COMMENT ON COLUMN ORA9.BUDGET.BUDGET_AMT IS '편성금액';
주석이 생성되었습니다.
SQL>
ALTER TABLE ORA9.BUDGET ADD (
2 CONSTRAINT BUDGET_PK PRIMARY KEY ( DEPT_NO, ACCOUNT, BUDGET_YR )
3 USING INDEX TABLESPACE ORA9 );
테이블이 변경되었습니다.
SQL>
INSERT INTO ORA9.CUSTOMER VALUES('0001','고객1');
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.CUSTOMER VALUES('0002','고객2');
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.CUSTOMER VALUES('0003','고객3');
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.CUSTOMER VALUES('0004','고객4');
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.CUSTOMER VALUES('0005','고객5');
1 개의 행이 만들어졌습니다.
SQL>
COMMIT;
커밋이 완료되었습니다.
SQL>
INSERT INTO ORA9.EMPLOYEE VALUES('0001','개발','1');
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.EMPLOYEE VALUES('0002','영업','2');
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.EMPLOYEE VALUES('0003','마케팅','1');
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.EMPLOYEE VALUES('0004','경영','3');
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.EMPLOYEE VALUES('0005','지원','1');
1 개의 행이 만들어졌습니다.
SQL>
COMMIT;
커밋이 완료되었습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0001','1101','2009',3000000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0001','1101','2008',2500000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0001','1102','2009',3500000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0001','1102','2008',2800000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0002','1101','2009',2500000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0002','1101','2008',2000000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0002','1102','2009',4500000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0002','1102','2008',3600000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0003','1101','2009',3200000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0003','1101','2008',2400000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0003','1102','2009',3300000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0003','1102','2008',2700000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0004','1101','2009',4400000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0004','1101','2008',3800000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0004','1102','2009',2500000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0004','1102','2008',1800000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0005','1101','2009',3300000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0005','1101','2008',2900000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0005','1102','2009',3700000);
1 개의 행이 만들어졌습니다.
SQL>
INSERT INTO ORA9.BUDGET VALUES('0005','1102','2008',3000000);
1 개의 행이 만들어졌습니다.
SQL>
COMMIT;
커밋이 완료되었습니다.
(1)SQL 분리시
SQL>
CREATE OR REPLACE PROCEDURE NOREL_JOIN_PRO1
2
3 (P_CUST_NO ORA9.CUSTOMER.CUST_NO%TYPE,
4 P_EMP_NO ORA9.EMPLOYEE.EMP_NO%TYPE,
5 P_DEPT_NO ORA9.BUDGET.DEPT_NO%TYPE
6 )
7
8 IS
9
10 CURSOR CUSTOMER_CSR IS
11 SELECT CUST_NAME
12 FROM ORA9.CUSTOMER
13 WHERE CUST_NO = P_CUST_NO;
14
15 CURSOR EMPLOYEE_CSR IS
16 SELECT DEPT
17 FROM ORA9.EMPLOYEE
18 WHERE EMP_NO = P_EMP_NO;
19
20 CURSOR BUDGET_CSR IS
21 SELECT BUDGET_AMT
22 FROM ORA9.BUDGET
23 WHERE DEPT_NO = P_DEPT_NO
24 AND ACCOUNT = '1101'
25 AND BUDGET_YR = TO_CHAR(SYSDATE, 'YYYY');
26
27 C_CUST_NM ORA9.CUSTOMER.CUST_NAME%TYPE;
28
29 C_DEPT ORA9.EMPLOYEE.DEPT%TYPE;
30
31 C_BUDGET_AMT ORA9.BUDGET.BUDGET_AMT%TYPE;
32
33 BEGIN
34
35 OPEN CUSTOMER_CSR;
36
37 LOOP
38
39 FETCH CUSTOMER_CSR INTO C_CUST_NM;
40
41 EXIT WHEN CUSTOMER_CSR%NOTFOUND;
42
43 DBMS_OUTPUT.PUT_LINE('고객명 : ' || C_CUST_NM);
44
45 OPEN EMPLOYEE_CSR;
46
47 LOOP
48
49 FETCH EMPLOYEE_CSR INTO C_DEPT;
50
51 EXIT WHEN EMPLOYEE_CSR%NOTFOUND;
52
53 DBMS_OUTPUT.PUT_LINE('부서 : ' || C_DEPT);
54
55 OPEN BUDGET_CSR;
56
57 LOOP
58
59 FETCH BUDGET_CSR INTO C_BUDGET_AMT;
60
61 EXIT WHEN BUDGET_CSR%NOTFOUND;
62
63 DBMS_OUTPUT.PUT_LINE('편성금액 : ' || C_BUDGET_AMT);
64
65 END LOOP;
66
67 CLOSE BUDGET_CSR;
68
69 END LOOP;
70
71 CLOSE EMPLOYEE_CSR;
72
73 END LOOP;
74
75 CLOSE CUSTOMER_CSR;
76
77 EXCEPTION
78
79 WHEN OTHERS THEN
80
81 DBMS_OUTPUT.PUT_LINE(SQLERRM||'에러 발생');
82
83 END;
84 /
프로시저가 생성되었습니다.
SQL>
SET SERVEROUTPUT ON;
SQL>
EXECUTE NOREL_JOIN_PRO1('0001','0001','0001');
고객명 : 고객1
부서 : 개발
편성금액 : 3000000
PL/SQL 처리가 정상적으로 완료되었습니다.
(2)SQL 통합시
SQL>
CREATE OR REPLACE PROCEDURE NOREL_JOIN_PRO2
2
3 (P_CUST_NO ORA9.CUSTOMER.CUST_NO%TYPE,
4 P_EMP_NO ORA9.EMPLOYEE.EMP_NO%TYPE,
5 P_DEPT_NO ORA9.BUDGET.DEPT_NO%TYPE
6 )
7
8 IS
9
10 CURSOR NOREL_JOIN_CSR IS
11 SELECT CUST_NAME
12 ,DEPT
13 ,BUDGET_AMT
14 FROM ORA9.CUSTOMER, ORA9.EMPLOYEE, ORA9.BUDGET
15 WHERE CUST_NO = P_CUST_NO
16 AND EMP_NO = P_EMP_NO
17 AND DEPT_NO = P_DEPT_NO
18 AND ACCOUNT = '1101'
19 AND BUDGET_YR = TO_CHAR(SYSDATE, 'YYYY');
20
21 C_CUST_NM ORA9.CUSTOMER.CUST_NAME%TYPE;
22
23 C_DEPT ORA9.EMPLOYEE.DEPT%TYPE;
24
25 C_BUDGET_AMT ORA9.BUDGET.BUDGET_AMT%TYPE;
26
27 BEGIN
28
29 OPEN NOREL_JOIN_CSR;
30
31 LOOP
32
33 FETCH NOREL_JOIN_CSR INTO C_CUST_NM,C_DEPT,C_BUDGET_AMT;
34
35 EXIT WHEN NOREL_JOIN_CSR%NOTFOUND;
36
37 DBMS_OUTPUT.PUT_LINE('고객명 : ' || C_CUST_NM);
38
39 DBMS_OUTPUT.PUT_LINE('부서 : ' || C_DEPT);
40
41 DBMS_OUTPUT.PUT_LINE('편성금액 : ' || C_BUDGET_AMT);
42
43 END LOOP;
44
45 CLOSE NOREL_JOIN_CSR;
46
47 EXCEPTION
48
49 WHEN OTHERS THEN
50
51 DBMS_OUTPUT.PUT_LINE(SQLERRM||'에러 발생');
52
53 END;
54 /
프로시저가 생성되었습니다.
SQL>
SET SERVEROUTPUT ON;
SQL>
EXECUTE NOREL_JOIN_PRO2('0001','0001','0001');
고객명 : 고객1
부서 : 개발
편성금액 : 3000000
PL/SQL 처리가 정상적으로 완료되었습니다.
(3)OUTER JOIN으로 SQL 통합시(실패)
SQL>
CREATE OR REPLACE PROCEDURE NOREL_JOIN_PRO3
2
3 (P_CUST_NO ORA9.CUSTOMER.CUST_NO%TYPE,
4 P_EMP_NO ORA9.EMPLOYEE.EMP_NO%TYPE,
5 P_DEPT_NO ORA9.BUDGET.DEPT_NO%TYPE
6 )
7
8 IS
9
10 CURSOR NOREL_JOIN_CSR IS
11 SELECT CUST_NAME
12 ,DEPT
13 ,BUDGET_AMT
14 FROM ORA9.CUSTOMER, ORA9.EMPLOYEE, ORA9.BUDGET
15 WHERE CUST_NO = P_CUST_NO
16 AND EMP_NO = P_EMP_NO
17 AND DEPT_NO(+) = P_DEPT_NO
18 AND ACCOUNT(+) = '1100'
19 AND BUDGET_YR(+) = TO_CHAR(SYSDATE, 'YYYY');
20
21 C_CUST_NM ORA9.CUSTOMER.CUST_NAME%TYPE;
22
23 C_DEPT ORA9.EMPLOYEE.DEPT%TYPE;
24
25 C_BUDGET_AMT ORA9.BUDGET.BUDGET_AMT%TYPE;
26
27 BEGIN
28
29 OPEN NOREL_JOIN_CSR;
30
31 LOOP
32
33 FETCH NOREL_JOIN_CSR INTO C_CUST_NM,C_DEPT,C_BUDGET_AMT;
34
35 EXIT WHEN NOREL_JOIN_CSR%NOTFOUND;
36
37 DBMS_OUTPUT.PUT_LINE('고객명 : ' || C_CUST_NM);
38
39 DBMS_OUTPUT.PUT_LINE('부서 : ' || C_DEPT);
40
41 DBMS_OUTPUT.PUT_LINE('편성금액 : ' || C_BUDGET_AMT);
42
43 END LOOP;
44
45 CLOSE NOREL_JOIN_CSR;
46
47 EXCEPTION
48
49 WHEN OTHERS THEN
50
51 DBMS_OUTPUT.PUT_LINE(SQLERRM||'에러 발생');
52
53 END;
54 /
프로시저가 생성되었습니다.
SQL>
SET SERVEROUTPUT ON;
SQL>
EXECUTE NOREL_JOIN_PRO3('0001','0001','0001');
PL/SQL 처리가 정상적으로 완료되었습니다. \--> 결과값이 출력되지 않았음
(4)OUTER JOIN으로 SQL 통합시(성공)
SQL>
CREATE OR REPLACE PROCEDURE NOREL_JOIN_PRO4
2
3 (P_CUST_NO ORA9.CUSTOMER.CUST_NO%TYPE,
4 P_EMP_NO ORA9.EMPLOYEE.EMP_NO%TYPE,
5 P_DEPT_NO ORA9.BUDGET.DEPT_NO%TYPE
6 )
7
8 IS
9
10 CURSOR NOREL_JOIN_CSR IS
11 SELECT CUST_NAME
12 ,DEPT
13 ,BUDGET_AMT
14 FROM ORA9.CUSTOMER, ORA9.EMPLOYEE, ORA9.BUDGET
15 WHERE CUST_NO = P_CUST_NO
16 AND EMP_NO = P_EMP_NO
17 AND DEPT_NO(+) = P_DEPT_NO || SUBSTR(EMP_NO,0,0)
18 AND ACCOUNT(+) = '1100'
19 AND BUDGET_YR(+) = TO_CHAR(SYSDATE, 'YYYY');
20
21 C_CUST_NM ORA9.CUSTOMER.CUST_NAME%TYPE;
22
23 C_DEPT ORA9.EMPLOYEE.DEPT%TYPE;
24
25 C_BUDGET_AMT ORA9.BUDGET.BUDGET_AMT%TYPE;
26
27 BEGIN
28
29 OPEN NOREL_JOIN_CSR;
30
31 LOOP
32
33 FETCH NOREL_JOIN_CSR INTO C_CUST_NM,C_DEPT,C_BUDGET_AMT;
34
35 EXIT WHEN NOREL_JOIN_CSR%NOTFOUND;
36
37 DBMS_OUTPUT.PUT_LINE('고객명 : ' || C_CUST_NM);
38
39 DBMS_OUTPUT.PUT_LINE('부서 : ' || C_DEPT);
40
41 DBMS_OUTPUT.PUT_LINE('편성금액 : ' || C_BUDGET_AMT);
42
43 END LOOP;
44
45 CLOSE NOREL_JOIN_CSR;
46
47 EXCEPTION
48
49 WHEN OTHERS THEN
50
51 DBMS_OUTPUT.PUT_LINE(SQLERRM||'에러 발생');
52
53 END;
54 /
프로시저가 생성되었습니다.
SQL>
SET SERVEROUTPUT ON;
SQL>
EXECUTE NOREL_JOIN_PRO4('0001','0001','0001');
고객명 : 고객1
부서 : 개발
편성금액 :
PL/SQL 처리가 정상적으로 완료되었습니다.
NOREL_JOIN_PRO3의 경우는 만족하는 값이 없으면 OUTER-JOIN 을 했다 하더라도 항상 공집합이다.
즉, DEPT_NO(+) = P_DEPT_NO 는 DEPT_NO = P_DEPT_NO 와 같은 결과를 낸다.
OUTER-JOIN 은 반드시 성공한 어떤 집합과 연결을 할 때만 의미가 있다.
즉, 상수값과는 OUTER-JOIN을 해도 결과는 달라지지 않는다.
반면 NOREL_JOIN_PRO4 에서는
CUST_NO = P_CUST_NO, EMP_NO = P_EMP_NO 를 만족하는 집합이 BUDGET 테이블과 OUTER-JOIN을 시도하는데,
DEPT_NO(+) = P_DEPT_NO || SUBSTR(EMP_NO,0,0) 조건을 보면
SUBSTR(EMP_NO,0,0)은 NULL 값이 되므로 P_DEPT_NO에 붙이더라도 그 결과에는 영향을 미치지 않는다.
이 구문의 추가로 인해 EMPLOYEE 테이블의 수행 결과는 BUDGET 테이블의 수행 결과에 영향을 받지 않는다.