프로젝트 개요

  • 구현 목표
    쌍용교육센터 운영을 위한 데이터베이스와 추가 기능을 구현한다.
  • 활동 내용
    • 1. 팀장 역할을 맡아 일정 조율 및 업무 분담, 최종 코드 점검 및 통합 작업을 수행
    • 2. 강의스케줄, 교육생수급내역, 과제리스트, 과제제출리스트 쿼리 작성
    • 3. 비품 관련, 출입카드 관련, 상담 관련 등 더미 데이터 생성
    • 4. ANSI-SQL, PL/SQL 시연 영상 제작
  • Category
  • 오라클 프로젝트
  • Period
  • 2023.09.11.~2023.09.18.
  • GitHub
  • https://github.com/Isaac-Seungwon/education-center-management-system.git
  • 시연 영상
  • 오라클 프로젝트 시연 영상 (Youtube)

강의 스케줄 (tblLectureSchedule)

--강의 스케줄 (tblLectureSchedule)
--C01-01. 강의 스케줄 조회
--특정 교사의 강의 스케줄을 출력
SELECT
    t.teacherName AS 교사이름,
    c.courseName AS 과정명,
    CASE
        WHEN sysdate < cd.courseStartDate THEN '강의예정'
        WHEN sysdate BETWEEN cd.courseStartDate AND cd.courseEndDate THEN '강의중'
        WHEN sysdate > cd.courseEndDate THEN '강의종료'
    END AS "강의진행여부",
    TO_CHAR(cd.courseStartDate, 'YYYY-MM-DD') AS "과정기간(시작 년월일)",
    TO_CHAR(cd.courseEndDate, 'YYYY-MM-DD') AS "과정기간(끝 년월일)",
    cd.lectureRoomNum AS 강의실,
    s.subjectName AS 과목명,
    TO_CHAR(sd.subjectStartDate, 'YYYY-MM-DD') AS "과목기간(시작 년월일)",
    TO_CHAR(sd.subjectEndDate, 'YYYY-MM-DD') AS "과목기간(끝 년월일)",
    tb.textBookName AS 교재명,
    (
    SELECT
    	COUNT(*)
    FROM tblStudent u
    	WHERE u.courseDetailNum = cd.courseDetailNum
    ) AS "교육생 등록 인원"
FROM tblLectureSchedule l
	INNER JOIN tblSubjectDetail sd
		ON l.subjectDetailNum = sd.subjectDetailNum
			INNER JOIN tblCourseDetail cd
				ON cd.courseDetailNum = sd.courseDetailNum
					INNER JOIN tblCourse c
						ON cd.courseNum = c.courseNum
							INNER JOIN tblSubject s
								ON s.subjectNum = sd.subjectNum
									INNER JOIN tblAvailableLecture al
										ON al.subjectNum = s.subjectNum
											INNER JOIN tblTeacher t
												ON t.teacherNum = al.teacherNum
													LEFT OUTER JOIN tblTextBook tb
														ON s.subjectNum = tb.subjectNum
WHERE t.teacherNum = 1 --체제투
ORDER BY 
    CASE
        WHEN sysdate BETWEEN cd.courseStartDate AND cd.courseEndDate THEN 1
        WHEN sysdate < cd.courseStartDate THEN 2
        WHEN sysdate > cd.courseEndDate THEN 3
    END,
    cd.courseStartDate ASC;

--SELECT
--    t.teacherName AS 교사이름,
--    s.subjectNum AS 과목번호,
--    c.courseName AS 과정명,
--    CASE
--        WHEN sysdate < cd.courseStartDate THEN '강의 예정'
--        WHEN sysdate BETWEEN cd.courseStartDate AND cd.courseEndDate THEN '강의중'
--        WHEN sysdate > cd.courseEndDate THEN '강의 종료'
--    END AS "강의진행여부",
--    TO_CHAR(cd.courseStartDate, 'YYYY-MM-DD') AS "과정기간(시작 년월일)",
--    TO_CHAR(cd.courseEndDate, 'YYYY-MM-DD') AS "과정기간(끝 년월일)",
--    cd.lectureRoomNum AS 강의실,
--    s.subjectName AS 과목명,
--    TO_CHAR(sd.subjectStartDate, 'YYYY-MM-DD') AS "과목기간(시작 년월일)",
--    TO_CHAR(sd.subjectEndDate, 'YYYY-MM-DD') AS "과목기간(끝 년월일)",
--    tb.textBookName AS 교재명,
--    (
--    SELECT
--    	COUNT(*)
--    FROM tblStudent u
--    	WHERE u.courseDetailNum = cd.courseDetailNum
--    ) AS "교육생 등록 인원"
--FROM tblLectureSchedule l
--	INNER JOIN tblSubjectDetail sd
--		ON l.subjectDetailNum = sd.subjectDetailNum
--			INNER JOIN tblCourseDetail cd
--				ON cd.courseDetailNum = sd.courseDetailNum
--					INNER JOIN tblCourse c
--						ON cd.courseNum = c.courseNum
--							INNER JOIN tblSubject s
--								ON s.subjectNum = sd.subjectNum
--									INNER JOIN tblAvailableLecture al
--										ON al.subjectNum = s.subjectNum
--											INNER JOIN tblTeacher t
--												ON t.teacherNum = al.teacherNum
--													LEFT OUTER JOIN tblTextBook tb
--														ON s.subjectNum = tb.subjectNum
--															WHERE t.teacherNum = <교사번호>
--ORDER BY 
--    CASE
--        WHEN sysdate BETWEEN cd.courseStartDate AND cd.courseEndDate THEN 1
--        WHEN sysdate < cd.courseStartDate THEN 2
--        WHEN sysdate > cd.courseEndDate THEN 3
--    END,
--    cd.courseStartDate ASC;

--교육중인 과정에 등록된 교육생의 정보 출력
SELECT DISTINCT
	o.courseName AS 과정명,
	i.interviewerName AS 교육생이름,
	i.interviewerTel AS 전화번호,
	TO_CHAR(s.registrationDate, 'YYYY-MM-DD') AS 등록일,
	NVL (
		(SELECT f.failReason
			FROM tblFail f
				WHERE f.studentNum = s.studentNum AND ROWNUM = 1
			), '수료'
	)AS 수료여부
FROM tblLectureSchedule l
	INNER JOIN tblSubjectDetail sd
		ON l.subjectDetailNum = sd.subjectDetailNum
			INNER JOIN tblCourseDetail cd
				ON cd.courseDetailNum = sd.courseDetailNum
					INNER JOIN tblStudent s
						ON cd.courseDetailNum = s.courseDetailNum
							INNER JOIN tblInterviewRegister r
								ON s.interviewRegiNum = r.interviewRegiNum
									INNER JOIN tblInterviewer i
										ON i.interviewerNum = r.interviewerNum
											LEFT OUTER JOIN tblComplete c
												ON c.studentNum = s.studentNum
													LEFT OUTER JOIN tblFail f
														ON c.studentNum = f.studentNum
															INNER JOIN tblCourseDetail cd
																ON s.courseDetailNum = cd.courseDetailNum
																	INNER JOIN tblCourse o
																		ON o.courseNum = cd.courseNum
WHERE cd.courseStartDate <= SYSDATE AND cd.courseEndDate >= SYSDATE --교육중인 과정
ORDER BY o.courseName, i.interviewerName;

--과정기간(끝 년월일)이 현재일 이후면서 '강의 종료'로 전환되지 않는 과정 조회
SELECT
    t.teacherName AS 교사이름,
    c.courseName AS 과정명,
    l.progress AS 강의진행여부,
    TO_CHAR(cd.courseStartDate, 'YYYY-MM-DD') AS "과정기간(시작 년월일)",
    TO_CHAR(cd.courseEndDate, 'YYYY-MM-DD') AS "과정기간(끝 년월일)",
    cd.lectureRoomNum AS 강의실,
    s.subjectName AS 과목명,
    TO_CHAR(sd.subjectStartDate, 'YYYY-MM-DD') AS "과목기간(시작 년월일)",
    TO_CHAR(sd.subjectEndDate, 'YYYY-MM-DD') AS "과목기간(끝 년월일)",
    tb.textBookName AS 교재명,
    (
    SELECT
    	COUNT(*)
    FROM tblStudent u
    	WHERE u.courseDetailNum = cd.courseDetailNum
    ) AS "교육생 등록 인원"
FROM tblLectureSchedule l
	INNER JOIN tblSubjectDetail sd
		ON l.subjectDetailNum = sd.subjectDetailNum
			INNER JOIN tblCourseDetail cd
				ON cd.courseDetailNum = sd.courseDetailNum
					INNER JOIN tblCourse c
						ON cd.courseNum = c.courseNum
							INNER JOIN tblSubject s
								ON s.subjectNum = sd.subjectNum
									INNER JOIN tblAvailableLecture al
										ON al.subjectNum = s.subjectNum
											INNER JOIN tblTeacher t
												ON t.teacherNum = al.teacherNum
													LEFT OUTER JOIN tblTextBook tb
														ON s.subjectNum = tb.subjectNum
WHERE cd.courseEndDate <= sysdate AND l.progress <> '강의종료'
ORDER BY cd.courseStartDate ASC;

교육생 수급내역 (tblStudentSupply)

--교육생 수급내역 (tblStudentSupply)
--D09-01. 교육생 지원금 수급
SELECT
	o.courseName AS 과정명,
	i.interviewerName AS 교육생이름,
	i.interviewerTel AS 전화번호,
	TO_CHAR(p.supplyDate, 'YYYY-MM-DD') AS 수급일,
	p.supplySum as 수급액
FROM tblStudentSupply p
	INNER JOIN tblStudent s
		ON p.studentNum = s.studentNum
			INNER JOIN tblInterviewRegister r
				ON s.interviewRegiNum = r.interviewRegiNum
					INNER JOIN tblInterviewer i
						ON i.interviewerNum = r.interviewerNum
							INNER JOIN tblCourseDetail cd
								ON s.courseDetailNum = cd.courseDetailNum
									INNER JOIN tblCourse o
										ON o.courseNum = cd.courseNum;

과제 제출 리스트 (tblAssignmentSubmit)

--과제 제출 리스트 (tblAssignmentSubmit)
--C07-01. 과제 등록 및 관리

--입력
INSERT INTO tblAssignment (assignmentNum, subjectDetailNum, assignmentContent)
			VALUES , <과제내용>);

--출력
--과제를 제출한 학생 명단 출력
SELECT
	c.courseName AS 과정명,
	s.subjectName AS 과목명,
	a.assignmentContent AS 과제명,
	sb.assignmentSubmitNum AS 과제제출번호,
	v.studentName AS 교육생이름,
	sb.assignmentExplain AS 과제풀이
FROM tblAssignmentSubmit sb
	INNER JOIN tblAssignment a
		ON a.assignmentNum = sb.assignmentNum
			INNER JOIN tblSubjectDetail sd
				ON a.subjectDetailNum = sd.subjectDetailNum
					INNER JOIN tblSubject s
						ON s.subjectNum = sd.subjectNum
							INNER JOIN tblCourseDetail cd
								ON cd.courseDetailNum = sd.courseDetailNum
									INNER JOIN tblCourse c
										ON c.courseNum = cd.courseNum
											INNER JOIN vwStudent v
												ON v.studentNum = sb.studentNum
WHERE cd.courseDetailNum = 1 --프로젝트기반 프론트엔드 웹,앱 SW발자 양성 과정
ORDER BY s.subjectName ASC;

--SELECT
--	c.courseName AS 과정명,
--	s.subjectName AS 과목명,
--	a.assignmentContent AS 과제명,
--	sb.assignmentSubmitNum AS 과제제출번호,
--	v.studentName AS 교육생이름,
--	sb.assignmentExplain AS 과제풀이
--FROM tblAssignmentSubmit sb
--	INNER JOIN tblAssignment a
--		ON a.assignmentNum = sb.assignmentNum
--			INNER JOIN tblSubjectDetail sd
--				ON a.subjectDetailNum = sd.subjectDetailNum
--					INNER JOIN tblSubject s
--						ON s.subjectNum = sd.subjectNum
--							INNER JOIN tblCourseDetail cd
--								ON cd.courseDetailNum = sd.courseDetailNum
--									INNER JOIN tblCourse c
--										ON c.courseNum = cd.courseNum
--											INNER JOIN vwStudent v
--												ON v.studentNum = sb.studentNum
--WHERE cd.courseDetailNum = <과정상세번호>
--ORDER BY s.subjectName ASC;

--수정
UPDATE tblAssignment
	SET subjectDetailNum = 1, assignmentContent = '자바심화과제1'
		WHERE assignmentNum = 1;
--UPDATE tblAssignment
--	SET subjectDetailNum = <과목상세번호>, assignmentContent = <과제내용>
--		WHERE assignmentNum = <수정하려는 과제번호>;

--삭제
DELETE FROM tblAssignment WHERE assignmentNum = 1;
--DELETE FROM tblAssignment WHERE assignmentNum = <삭제하려는 과제번호>;

과제 리스트 (tblAssignment)

--과제 리스트 (tblAssignment)
--D06-01. 과제 제출 및 조회
--입력
INSERT INTO tblAssignmentSubmit (AssignmentSubmitNum, AssignmentNum, studentNum, assignmentExplain)
    VALUES (seqAssignmentSubmit.nextVal, 660, 27, CSS과제3 풀이);
--INSERT INTO tblAssignmentSubmit (assignmentSubmitNum, assignmentNum, studentNum, assignmentExplain)
--    VALUES (seqAssignmentSubmit.nextVal, <과제번호>, <교육생번호>, <과제풀이>);

--출력
--본인을 포함한 같은 과정을 수강중인 학생들의 과제 명단 출력
SELECT
	c.courseName AS 과정명,
	s.subjectName AS 과목명,
	a.assignmentContent AS 과제명,
	sb.assignmentSubmitNum AS 과제제출번호,
	st.studentName AS 교육생이름,
	sb.assignmentExplain AS 과제풀이
FROM tblAssignmentSubmit sb
	INNER JOIN tblAssignment a
		ON a.assignmentNum = sb.assignmentNum
			INNER JOIN tblSubjectDetail sd
				ON a.subjectDetailNum = sd.subjectDetailNum
					INNER JOIN tblSubject s
						ON s.subjectNum = sd.subjectNum
							INNER JOIN tblCourseDetail cd
								ON cd.courseDetailNum = sd.courseDetailNum
									INNER JOIN tblCourse c
										ON c.courseNum = cd.courseNum
											INNER JOIN vwStudent st
       											ON st.studentNum = sb.studentNum
WHERE (c.courseName, s.subjectName)
	IN(
	    SELECT
	        c2.courseName,
	        s2.subjectName
	    FROM tblAssignmentSubmit sb2
	        INNER JOIN tblAssignment a2
	        	ON a2.assignmentNum = sb2.assignmentNum
			        INNER JOIN tblSubjectDetail sd2
			        	ON a2.subjectDetailNum = sd2.subjectDetailNum
					        INNER JOIN tblSubject s2
					        	ON s2.subjectNum = sd2.subjectNum
							        INNER JOIN tblCourseDetail cd2
							        	ON cd2.courseDetailNum = sd2.courseDetailNum
							        		INNER JOIN tblCourse c2
							        			ON c2.courseNum = cd2.courseNum
													INNER JOIN vwStudent st2
		       											ON st2.studentNum = sb2.studentNum
	    WHERE sb2.studentNum = 1
	    	AND s.subjectName = '오라클'
);

--SELECT
--	c.courseName AS 과정명,
--	s.subjectName AS 과목명,
--	a.assignmentContent AS 과제명,
--	sb.assignmentSubmitNum AS 과제제출번호,
--	st.studentName AS 교육생이름,
--	sb.assignmentExplain AS 과제풀이
--FROM tblAssignmentSubmit sb
--	INNER JOIN tblAssignment a
--		ON a.assignmentNum = sb.assignmentNum
--			INNER JOIN tblSubjectDetail sd
--				ON a.subjectDetailNum = sd.subjectDetailNum
--					INNER JOIN tblSubject s
--						ON s.subjectNum = sd.subjectNum
--							INNER JOIN tblCourseDetail cd
--								ON cd.courseDetailNum = sd.courseDetailNum
--									INNER JOIN tblCourse c
--										ON c.courseNum = cd.courseNum
--											INNER JOIN vwStudent st
--       											ON st.studentNum = sb.studentNum
--WHERE (c.courseName, s.subjectName)
--	IN(
--	    SELECT
--	        c2.courseName,
--	        s2.subjectName
--	    FROM tblAssignmentSubmit sb2
--	        INNER JOIN tblAssignment a2
--	        	ON a2.assignmentNum = sb2.assignmentNum
--			        INNER JOIN tblSubjectDetail sd2
--			        	ON a2.subjectDetailNum = sd2.subjectDetailNum
--					        INNER JOIN tblSubject s2
--					        	ON s2.subjectNum = sd2.subjectNum
--							        INNER JOIN tblCourseDetail cd2
--							        	ON cd2.courseDetailNum = sd2.courseDetailNum
--							        		INNER JOIN tblCourse c2
--							        			ON c2.courseNum = cd2.courseNum
--													INNER JOIN vwStudent st2
--		       											ON st2.studentNum = sb2.studentNum
--	    WHERE sb2.studentNum = <교육생번호>
--	    	AND s.subjectName = <과목명>
--);

--수정
UPDATE tblAssignmentSubmit
	SET assignmentNum = 5, studentNum = 25, assignmentExplain = '오라클과제1 풀이'
		WHERE assignmentSubmitNum = 437;
--UPDATE tblAssignmentSubmit
--	SET assignmentNum = <과제번호>, studentNum = <교육생번호>, assignmentExplain = <과제풀이>
--		WHERE assignmentSubmitNum = <수정하려는 과제제출번호>;

--삭제
DELETE FROM tblAssignmentSubmit WHERE assignmentSubmitNum = 2584;
--DELETE FROM tblAssignmentSubmit WHERE assignmentSubmitNum = <삭제하려는 과제제출번호>;

강의 스케줄 (tblLectureSchedule)

--강의 스케줄 (tblLectureSchedule)
--C01-01. 강의 스케줄 조회
--특정 교사의 강의 스케줄 출력 프로시저
CREATE OR REPLACE PROCEDURE procLectureSchedule (
    pTeacherNum IN VARCHAR2,
    pLectureScheduleCursor OUT SYS_REFCURSOR
)
IS
    vCount NUMBER;
BEGIN
    --타입 유효성 검사 (NUMBER)
    IF pTeacherNum IS NULL OR NOT REGEXP_LIKE(pTeacherNum, '^[0-9]+$') THEN
        DBMS_OUTPUT.PUT_LINE('유효하지 않은 교사 번호입니다.');
        RAISE_APPLICATION_ERROR(-20000, '유효하지 않은 교사 번호');
    END IF;

    --범위 유효성 검사
    SELECT COUNT(*) INTO vCount FROM tblTeacher WHERE teacherNum = pTeacherNum;
    IF vCount = 0 THEN
        DBMS_OUTPUT.PUT_LINE('해당 교사 번호의 강의 스케줄이 없습니다.');
        RAISE_APPLICATION_ERROR(-20001, '해당 교사 번호의 강의 스케줄 데이터 없음');
    END IF;

    --out parameter에 cursor 할당
    OPEN pLectureScheduleCursor FOR
    SELECT
        *
    FROM vwLectureSchedule
    WHERE teacherNum = pTeacherNum
    ORDER BY courseStartDate ASC;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procLectureSchedule;

--특정 교사의 강의 스케줄 출력 프로시저 호출
DECLARE
    vLectureScheduleCursor SYS_REFCURSOR;
    vTeacherNum tblTeacher.teacherNum%TYPE := <교사번호>; --1 (체제투)
    vRow vwLectureSchedule%ROWTYPE;
BEGIN
    procLectureSchedule(vTeacherNum, vLectureScheduleCursor); --procLectureSchedule 호출

    DBMS_OUTPUT.PUT_LINE('────────────────────── 강의 스케줄 정보 ──────────────────────');
    LOOP
        FETCH vLectureScheduleCursor INTO vRow;
		EXIT WHEN vLectureScheduleCursor%NOTFOUND;

        DBMS_OUTPUT.PUT_LINE('교사이름: ' || vRow.teacherName);
        DBMS_OUTPUT.PUT_LINE('과목번호: ' || vRow.subjectNum);
        DBMS_OUTPUT.PUT_LINE('과정명: ' || vRow.courseName);
        DBMS_OUTPUT.PUT_LINE('강의진행여부: ' || vRow.progress);
        DBMS_OUTPUT.PUT_LINE('과정기간(시작 년월일): ' || vROw.courseStartDate);
        DBMS_OUTPUT.PUT_LINE('과정기간(끝 년월일): ' || vROw.courseEndDate);
        DBMS_OUTPUT.PUT_LINE('강의실: ' || vRow.lectureRoomNum);
        DBMS_OUTPUT.PUT_LINE('과목명: ' || vRow.subjectName);
        DBMS_OUTPUT.PUT_LINE('과목기간(시작 년월일): ' || vRow.subjectStartDate);
        DBMS_OUTPUT.PUT_LINE('과목기간(끝 년월일): ' || vRow.subjectEndDate);
        DBMS_OUTPUT.PUT_LINE('교재명: ' || vROw.textBookName);
        DBMS_OUTPUT.PUT_LINE('교육생 등록 인원: ' || vRow.register);
        DBMS_OUTPUT.PUT_LINE('──────────────────────────────────────────────────────────────');
    END LOOP;
    CLOSE vLectureScheduleCursor;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('조회에 실패했습니다.');
END;


--교육중인 과정에 등록된 교육생의 정보 출력 프로시저
CREATE OR REPLACE PROCEDURE procStudentCourseStatus (
    pCourseNum IN VARCHAR2,
    pCourseCursor OUT SYS_REFCURSOR
)
IS
BEGIN
    OPEN pCourseCursor FOR
    SELECT
    	*
    FROM vwStudentCourseStatus
    WHERE courseNum = pCourseNum
    ORDER BY courseName, interviewerName;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procStudentCourseStatus;

--교육중인 과정에 등록된 교육생의 정보 출력 프로시저 호출
DECLARE
    vCourseCursor SYS_REFCURSOR;
    vCourseNum tblCourse.courseNum%TYPE := <과정번호>; --1 (AWS를 활용한 클라우드 자바 웹기반 풀스텍 개발자 과정)
    vRow vwStudentCourseStatus%ROWTYPE;
BEGIN
    procStudentCourseStatus(vCourseNum, vCourseCursor); --procStudentCourseStatus 호출

    DBMS_OUTPUT.PUT_LINE('────────────────────── 등록 교육생 정보 ──────────────────────');
    LOOP
        FETCH vCourseCursor INTO vRow;
		EXIT WHEN vCourseCursor%NOTFOUND;

        DBMS_OUTPUT.PUT_LINE('과정명: ' || vRow.courseName);
        DBMS_OUTPUT.PUT_LINE('교육생이름: ' || vRow.interviewerName);
        DBMS_OUTPUT.PUT_LINE('전화번호: ' || vRow.interviewerTel);
        DBMS_OUTPUT.PUT_LINE('등록일: ' || vRow.registrationDate);
        DBMS_OUTPUT.PUT_LINE('수료여부: ' || vRow.completionStatus);
        DBMS_OUTPUT.PUT_LINE('──────────────────────────────────────────────────────────────');
    END LOOP;
    CLOSE vCourseCursor;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('교육생 조회에 실패했습니다.');
END;

--강의가 종료된 강의의 진행 상태를 강의 종료로 갱신하는 프로시저
CREATE OR REPLACE PROCEDURE procUpdateCourseProgress AS
    CURSOR courseData IS
        SELECT cd.courseDetailNum, cd.courseEndDate, l.progress
        FROM tblCourseDetail cd
        	INNER JOIN tblLectureSchedule l
        		ON cd.courseDetailNum = l.subjectDetailNum;

    course courseData%ROWTYPE;
BEGIN
    OPEN courseData;
    LOOP
        FETCH courseData INTO course;
        EXIT WHEN courseData%NOTFOUND;

        IF course.courseEndDate <= sysdate AND course.progress <> '강의종료' THEN
            UPDATE tblLectureSchedule
            SET progress = '강의종료'
            WHERE subjectDetailNum = course.courseDetailNum;
            DBMS_OUTPUT.PUT_LINE('과정상세번호: ' || course.courseDetailNum || ' 강의종료로 갱신');
        END IF;
    END LOOP;
    CLOSE courseData;
END procUpdateCourseProgress;

교육생 수급내역 (tblStudentSupply)

--교육생 수급내역 (tblStudentSupply)
--D09-01. 교육생 지원금 수급
--교육생 수급 내역 프로시저
CREATE OR REPLACE PROCEDURE procStudentSupply (
    pCourseNum IN VARCHAR2,
    pSupplyCursor OUT SYS_REFCURSOR
)
IS
BEGIN
    OPEN pSupplyCursor FOR
    SELECT
		*
    FROM vwStudentSupply
    WHERE courseNum = pCourseNum; --과정번호
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procStudentSupply;

--교육생 수급 내역 프로시저 호출
DECLARE
    vSupplyCursor SYS_REFCURSOR; --cursor
    vCourseNum tblCourse.courseNum%TYPE := <과정번호>; --1
    vRow vwStudentSupply%ROWTYPE;
BEGIN
    procStudentSupply(vCourseNum, vSupplyCursor); --procStudentSupply 호출

    DBMS_OUTPUT.PUT_LINE('────────────────────── 교육생 수급 내역 ──────────────────────');
    LOOP
        FETCH vSupplyCursor INTO vRow;
        EXIT WHEN vSupplyCursor%NOTFOUND;

        DBMS_OUTPUT.PUT_LINE('과정명: ' || vRow.courseName);
        DBMS_OUTPUT.PUT_LINE('교육생이름: ' || vRow.interviewerName);
        DBMS_OUTPUT.PUT_LINE('전화번호: ' || vRow.interviewerTel);
        DBMS_OUTPUT.PUT_LINE('수급일: ' || vRow.supplyDate);
        DBMS_OUTPUT.PUT_LINE('수급액: ' || vRow.supplySum);
        DBMS_OUTPUT.PUT_LINE('──────────────────────────────────────────────────────────────');
    END LOOP;
    CLOSE vSupplyCursor;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('교육생 수급 내역 조회에 실패했습니다.');
END;

과제 제출 리스트 (tblAssignmentSubmit)

--과제 제출 리스트 (tblAssignmentSubmit)
--C07-01. 과제 등록 및 관리
--입력 (과제 등록)
CREATE OR REPLACE PROCEDURE procInsertAssignmentTeacher (
    pSubjectDetailNum IN VARCHAR2,
    pAssignmentContent IN VARCHAR2
)
IS
BEGIN
    INSERT INTO tblAssignment (assignmentNum, subjectDetailNum, assignmentContent)
    VALUES ((SELECT NVL(MAX(LPAD(assignmentNum, 8, '0')), 0) + 1 FROM tblAssignment), pSubjectDetailNum, pAssignmentContent);
	EXCEPTION
	    WHEN OTHERS THEN
	        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procInsertAssignmentTeacher;

--입력 프로시저 실행
DECLARE
    vSubjectDetailNum VARCHAR2(30) := <과목상세번호>; --3
    vAssignmentContent VARCHAR2(2048) := <과제내용>; --'자바과제4'
BEGIN
	procInsertAssignmentTeacher(vSubjectDetailNum, vAssignmentContent);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('등록에 실패했습니다.');
END;


--출력 (교육생 과제 제출 명단 출력)
--특정 과정의 교육생 과제 제출 명단 프로시저
CREATE OR REPLACE PROCEDURE procGetAssignmentList (
    pCourseDetailNum IN VARCHAR2,
    pAssignmentCursor OUT SYS_REFCURSOR
)
IS
BEGIN
    OPEN pAssignmentCursor FOR
    SELECT
       *
   	FROM vwAssignmentSubmitStudentList
    WHERE courseDetailNum = pCourseDetailNum; --과정상세번호
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procGetAssignmentList;

--특정 과정의 교육생 과제 제출 명단 프로시저 호출
DECLARE
    vAssignmentCursor SYS_REFCURSOR; --cursor
    vCourseDetailNum tblCourseDetail.courseDetailNum%TYPE := <과정상세번호>; --1
    vRow vwAssignmentSubmitStudentList%ROWTYPE;
BEGIN
    procGetAssignmentList(vCourseDetailNum, vAssignmentCursor); --procGetAssignmentList 호출

    DBMS_OUTPUT.PUT_LINE('──────────────────── 교육생 과제 제출 명단 ────────────────────');
    LOOP
        FETCH vAssignmentCursor INTO vRow;
        EXIT WHEN vAssignmentCursor%NOTFOUND;

        DBMS_OUTPUT.PUT_LINE('과정명: ' || vRow.CourseName);
        DBMS_OUTPUT.PUT_LINE('과목명: ' || vRow.SubjectName);
        DBMS_OUTPUT.PUT_LINE('과제내용: ' || vRow.AssignmentContent);
        DBMS_OUTPUT.PUT_LINE('과제제출번호: ' || vRow.AssignmentSubmitNum);
        DBMS_OUTPUT.PUT_LINE('교육생이름: ' || vRow.StudentName);
        DBMS_OUTPUT.PUT_LINE('과제풀이: ' || vRow.AssignmentExplain);
       	DBMS_OUTPUT.PUT_LINE('──────────────────────────────────────────────────────────────');
    END LOOP;
    CLOSE vAssignmentCursor;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('교육생 과제 제출 명단 조회에 실패했습니다.');
END;

--수정 (과제 수정)
CREATE OR REPLACE PROCEDURE procUpdateAssignmentTeacher (
    pAssignmentNum IN VARCHAR2,
    pSubjectDetailNum IN VARCHAR2,
    pAssignmentContent IN VARCHAR2
)
IS
BEGIN
    UPDATE tblAssignment
    SET subjectDetailNum = pSubjectDetailNum, assignmentContent = pAssignmentContent
    WHERE assignmentNum = pAssignmentNum;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procUpdateAssignmentTeacher;

--수정 프로시저 실행
DECLARE
    vAssignmentNum VARCHAR2(30) := <과제번호>; --1
    vSubjectDetailNum VARCHAR2(30) := <과목상세번호>; --1
    vAssignmentContent VARCHAR2(2048) := <과제내용>; --'자바과제 4풀이'
BEGIN
    procUpdateAssignmentTeacher(vAssignmentNum, vSubjectDetailNum, vAssignmentContent);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('갱신에 실패했습니다.');
END;

--삭제 (과제 삭제)
CREATE OR REPLACE PROCEDURE procDeleteAssignmentTeacher (
    pAssignmentNum IN VARCHAR2
)
IS
BEGIN
    DELETE FROM tblAssignment WHERE assignmentNum = pAssignmentNum;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procDeleteAssignmentTeacher;

--삭제 프로시저 실행
DECLARE
	vAssignmentNum VARCHAR2(30) := <과제번호>; --326
BEGIN
	procDeleteAssignmentTeacher(vAssignmentNum);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('삭제에 실패했습니다.');
END;

과제 리스트 (tblAssignment)

--과제 리스트 (tblAssignment)
--D06-01. 과제 제출 및 조회
--입력 (과제 제출)
CREATE OR REPLACE PROCEDURE procInsertAssignmentStudent (
    pAssignmentNum IN VARCHAR2,
    pStudentNum IN VARCHAR2,
    pAssignmentExplain IN VARCHAR2
)
IS
BEGIN
    INSERT INTO tblAssignmentSubmit (assignmentSubmitNum, assignmentNum, studentNum, assignmentExplain)
    VALUES ((SELECT NVL(MAX(LPAD(assignmentSubmitNum, 8, '0')), 0) + 1 FROM tblAssignmentSubmit), pAssignmentNum, pStudentNum, pAssignmentExplain);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procInsertAssignmentStudent;

--입력 프로시저 실행
DECLARE
    vAssignmentNum VARCHAR2(30) := <과제번호>; --1
    vStudentNum VARCHAR2(30) := <교육생번호>; --1
    vAssignmentExplain VARCHAR2(2048) := <과제풀이>; --'자바과제 4풀이'
BEGIN
	procInsertAssignmentStudent(vAssignmentNum, vStudentNum, vAssignmentExplain);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('등록에 실패했습니다.');
END;

--출력 (과제를 제출한 학생 명단 출력)
--학생 본인과 동일한 과정을 수강하는 학생의 과제 명단 프로시저
CREATE OR REPLACE PROCEDURE procReadAssignmentStudent (
    pStudentNum IN VARCHAR2,
    pSubjectName IN VARCHAR2,
    pAssignmentCursor OUT SYS_REFCURSOR
)
IS
BEGIN
    OPEN pAssignmentCursor FOR
    SELECT
        c.courseName AS 과정명,
        s.subjectName AS 과목명,
        a.assignmentContent AS 과제명,
        sb.assignmentSubmitNum AS 과제제출번호,
        st.studentName AS 교육생이름,
        sb.assignmentExplain AS 과제풀이
    FROM tblAssignmentSubmit sb
        INNER JOIN tblAssignment a
            ON a.assignmentNum = sb.assignmentNum
                INNER JOIN tblSubjectDetail sd
                    ON a.subjectDetailNum = sd.subjectDetailNum
                        INNER JOIN tblSubject s
                            ON s.subjectNum = sd.subjectNum
                                INNER JOIN tblCourseDetail cd
                                    ON cd.courseDetailNum = sd.courseDetailNum
                                        INNER JOIN tblCourse c
                                            ON c.courseNum = cd.courseNum
                                                INNER JOIN vwStudent st
                                                    ON st.studentNum = sb.studentNum
    WHERE (c.courseName, s.subjectName)
    IN (
        SELECT
            c2.courseName,
            s2.subjectName
        FROM tblAssignmentSubmit sb2
            INNER JOIN tblAssignment a2
                ON a2.assignmentNum = sb2.assignmentNum
                    INNER JOIN tblSubjectDetail sd2
                        ON a2.subjectDetailNum = sd2.subjectDetailNum
                            INNER JOIN tblSubject s2
                                ON s2.subjectNum = sd2.subjectNum
                                    INNER JOIN tblCourseDetail cd2
                                        ON cd2.courseDetailNum = sd2.courseDetailNum
                                            INNER JOIN tblCourse c2
                                                ON c2.courseNum = cd2.courseNum
                                                    INNER JOIN vwStudent st2
                                                        ON st2.studentNum = sb2.studentNum
        WHERE sb2.studentNum = pStudentNum --교육생번호
        AND s.subjectName = pSubjectName --과목명
    )
    ORDER BY c.courseName, s.subjectName, sb.studentNum, sb.assignmentSubmitNum;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procReadAssignmentStudent;


--학생 본인과 동일한 과정을 수강하는 학생의 과제 명단 프로시저 호출
DECLARE
    vStudentNum tblStudent.studentNum%TYPE := <교육생번호>; --1
    vSubjectName tblSubject.subjectName%TYPE := <과목명>; --'CSS'
    vAssignmentCursor SYS_REFCURSOR;
    vCourseName tblCourse.courseName%TYPE;
    vSubjectName tblSubject.subjectName%TYPE;
    vAssignmentName tblAssignment.assignmentContent%TYPE;
    vAssignmentSubmitNum tblAssignmentSubmit.assignmentSubmitNum%TYPE;
    vStudentName tblInterviewer.interviewerName%TYPE;
    vAssignmentExplanation tblAssignmentSubmit.assignmentExplain%TYPE;
BEGIN
    procReadAssignmentStudent(vStudentNum, vSubjectName, vAssignmentCursor); -- 과제를 제출한 학생 명단을 가져옴

    DBMS_OUTPUT.PUT_LINE('──────────────────── 교육생 제출 과제 조회 ────────────────────');
    LOOP
        FETCH vAssignmentCursor INTO
            vCourseName,
            vSubjectName,
            vAssignmentName,
            vAssignmentSubmitNum,
            vStudentName,
            vAssignmentExplanation;
        EXIT WHEN vAssignmentCursor%NOTFOUND;

        DBMS_OUTPUT.PUT_LINE('과정명: ' || vCourseName);
        DBMS_OUTPUT.PUT_LINE('과목명: ' || vSubjectName);
        DBMS_OUTPUT.PUT_LINE('과제명: ' || vAssignmentName);
        DBMS_OUTPUT.PUT_LINE('과제제출번호: ' || vAssignmentSubmitNum);
        DBMS_OUTPUT.PUT_LINE('교육생이름: ' || vStudentName);
        DBMS_OUTPUT.PUT_LINE('과제풀이: ' || vAssignmentExplanation);
        DBMS_OUTPUT.PUT_LINE('──────────────────────────────────────────────────────────────');
    END LOOP;
    CLOSE vAssignmentCursor;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('과제 명단 조회에 실패했습니다.');
END;

--수정 (과제 제출 수정)
CREATE OR REPLACE PROCEDURE procUpdateAssignmentStudent (
    pAssignmentSubmitNum IN VARCHAR2,
    pAssignmentNum IN VARCHAR2,
    pStudentNum IN VARCHAR2,
    pAssignmentExplain IN VARCHAR2
)
IS
BEGIN
    UPDATE tblAssignmentSubmit
    SET assignmentNum = pAssignmentNum, studentNum = pStudentNum, assignmentExplain = pAssignmentExplain
    WHERE assignmentSubmitNum = pAssignmentSubmitNum;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procUpdateAssignmentStudent;

--수정 프로시저 실행
DECLARE
    vAssignmentSubmitNum VARCHAR(30) := <과제제출번호>; --1
    vAssignmentNum VARCHAR2(30) := <과제번호>; --1
    vStudentNum VARCHAR2(30) := <교육생번호>; --1
    vAssignmentExplain VARCHAR2(2048) := <과제풀이>; --'자바과제 4풀이'
BEGIN
    procUpdateAssignmentStudent(vAssignmentNum, vStudentNum, vAssignmentExplain);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('갱신에 실패했습니다.');
END;

--삭제 (과제 제출 삭제)
CREATE OR REPLACE PROCEDURE procDeleteAssignmentStudent (
    pAssignmentSubmitNum IN VARCHAR2
)
IS
BEGIN
    DELETE FROM tblAssignmentSubmit WHERE assignmentSubmitNum = pAssignmentSubmitNum;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('생성에 실패했습니다.');
END procDeleteAssignmentStudent;

--삭제 프로시저 실행
DECLARE
	vAssignmentSubmitNum VARCHAR2(30) := <과제제출번호>; --9078
BEGIN
	procDeleteAssignmentStudent(vAssignmentSubmitNum);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('삭제에 실패했습니다.');
END;

학생 정보

--학생 정보
CREATE OR REPLACE VIEW vwStudent
AS
SELECT
   s.studentNum AS studentNum,
   i.interviewerName AS studentName,
   i.interviewerSsn AS studentSsn,
   i.interviewerTel AS studentTel
FROM tblInterviewer i
   INNER JOIN tblInterviewRegister r
      ON i.interviewerNum = r.interviewerNum
         INNER JOIN tblStudent s
            ON r.interviewRegiNum = s.interviewRegiNum;


CREATE OR REPLACE VIEW vwCompletionStatus
AS
SELECT
   s.studentNum AS studentNum,
   vs.studentName AS studentName,
   cd.courseDetailNum AS courseDetailNum,
   cs.courseNum AS courseNum,
   cs.courseName AS courseName,
   TO_CHAR(cd.courseStartDate,'YYYY-MM-DD') AS courseStartDate,
   TO_CHAR(cd.courseEndDate,'YYYY-MM-DD') AS courseEndDate,
   cd.lectureRoomNum AS lectureRoomNum,
   CASE 
      WHEN c.studentNum IS NOT NULL THEN '수료'
      WHEN f.studentNum IS NOT NULL THEN '중도 탈락'
      WHEN TO_CHAR(cd.courseStartDate,'YYYY-MM-DD') > TO_CHAR(sysdate,'YYYY-MM-DD') THEN '진행 예정'
      ELSE '진행중'
   END AS completionStatus,
   CASE
      WHEN c.studentNum IS NOT NULL THEN TO_CHAR(c.completeDate,'YYYY-MM-DD')
      WHEN f.studentNum IS NOT NULL THEN TO_CHAR(f.failDate,'YYYY-MM-DD')
      ELSE NULL
   END AS completionDate
FROM tblStudent s
   INNER JOIN tblCourseDetail cd
      ON s.courseDetailNum = cd.courseDetailNum
         INNER JOIN tblCourse cs
            ON cs.courseNum = cd.courseNum
               FULL OUTER JOIN tblComplete c
                  ON s.studentNum = c.studentNum
                     FULL OUTER JOIN tblFail f
                        ON s.studentNum = f.studentNum
                            INNER JOIN vwStudent vs
                                ON s.studentNum = vs.studentNum;

교사 강의 스케줄

--교사 강의 스케줄
CREATE OR REPLACE VIEW vwLectureSchedule
AS
SELECT
    t.teacherNum,
    t.teacherName,
    s.subjectNum,
    c.courseName,
    CASE
      WHEN sysdate < cd.courseStartDate THEN '강의 예정'
      WHEN sysdate BETWEEN cd.courseStartDate AND cd.courseEndDate THEN '강의중'
      WHEN sysdate > cd.courseEndDate THEN '강의 종료'
	END AS progress,
    TO_CHAR(cd.courseStartDate, 'YYYY-MM-DD') AS courseStartDate,
    TO_CHAR(cd.courseEndDate, 'YYYY-MM-DD') AS courseEndDate,
    cd.lectureRoomNum,
    s.subjectName,
    TO_CHAR(sd.subjectStartDate, 'YYYY-MM-DD') AS subjectStartDate,
    TO_CHAR(sd.subjectEndDate, 'YYYY-MM-DD') AS subjectEndDate,
    tb.textBookName,
    (
    SELECT
    	COUNT(*)
    FROM tblStudent u
    	WHERE u.courseDetailNum = cd.courseDetailNum
    ) AS register
FROM tblLectureSchedule l
	INNER JOIN tblSubjectDetail sd
		ON l.subjectDetailNum = sd.subjectDetailNum
			INNER JOIN tblCourseDetail cd
				ON cd.courseDetailNum = sd.courseDetailNum
					INNER JOIN tblCourse c
						ON cd.courseNum = c.courseNum
							INNER JOIN tblSubject s
								ON s.subjectNum = sd.subjectNum
									INNER JOIN tblAvailableLecture al
										ON al.subjectNum = s.subjectNum
											INNER JOIN tblTeacher t
												ON t.teacherNum = al.teacherNum
													LEFT OUTER JOIN tblTextBook tb
														ON s.subjectNum = tb.subjectNum
ORDER BY 
    CASE
        WHEN sysdate BETWEEN cd.courseStartDate AND cd.courseEndDate THEN 1
        WHEN sysdate < cd.courseStartDate THEN 2
        WHEN sysdate > cd.courseEndDate THEN 3
    END,
    cd.courseStartDate ASC;

--교사 강의 스케줄 뷰 호출
SELECT * FROM vwLectureSchedule ORDER BY vwLectureSchedule.teacherName, vwLectureSchedule.courseStartDate;

교육생의 등록일과 수료 여부

--교육생의 등록일과 수료 여부
CREATE OR REPLACE VIEW vwStudentCourseStatus
AS
SELECT DISTINCT
	o.courseNum,
	o.courseName,
	i.interviewerName,
	i.interviewerTel,
	TO_CHAR(s.registrationDate, 'YYYY-MM-DD') AS registrationDate,
	NVL (
		(SELECT f.failReason
			FROM tblFail f
				WHERE f.studentNum = s.studentNum AND ROWNUM = 1
			), '수료'
	)AS completionStatus
FROM tblLectureSchedule l
	INNER JOIN tblSubjectDetail sd
		ON l.subjectDetailNum = sd.subjectDetailNum
			INNER JOIN tblCourseDetail cd
				ON cd.courseDetailNum = sd.courseDetailNum
					INNER JOIN tblStudent s
						ON cd.courseDetailNum = s.courseDetailNum
							INNER JOIN tblInterviewRegister r
								ON s.interviewRegiNum = r.interviewRegiNum
									INNER JOIN tblInterviewer i
										ON i.interviewerNum = r.interviewerNum
											LEFT OUTER JOIN tblComplete c
												ON c.studentNum = s.studentNum
													LEFT OUTER JOIN tblFail f
														ON c.studentNum = f.studentNum
															INNER JOIN tblCourseDetail cd
																ON s.courseDetailNum = cd.courseDetailNum
																	INNER JOIN tblCourse o
																		ON o.courseNum = cd.courseNum
WHERE cd.courseStartDate <= SYSDATE AND cd.courseEndDate >= SYSDATE
ORDER BY o.courseName, i.interviewerName;

--교육생의 등록일과 수료 여부 뷰 호출
SELECT * FROM vwStudentCourseStatus;

교육생 수급내역

--교육생 수급내역
CREATE OR REPLACE VIEW vwStudentSupply
AS
SELECT
    o.courseNum,
    o.courseName,
    i.interviewerName,
    i.interviewerTel,
    TO_CHAR(p.supplyDate, 'YYYY-MM-DD') AS supplyDate,
    p.supplySum
FROM tblStudentSupply p
    INNER JOIN tblStudent s
        ON p.studentNum = s.studentNum
            INNER JOIN tblInterviewRegister r
                ON s.interviewRegiNum = r.interviewRegiNum
                    INNER JOIN tblInterviewer i
                        ON i.interviewerNum = r.interviewerNum
                            INNER JOIN tblCourseDetail cd
                                ON s.courseDetailNum = cd.courseDetailNum
                                    INNER JOIN tblCourse o
                                        ON o.courseNum = cd.courseNum;

--교육생 수급내역 뷰 호출
SELECT * FROM vwStudentSupply;

과제를 제출한 학생 명단

--과제를 제출한 학생 명단
CREATE OR REPLACE VIEW vwAssignmentSubmitStudentList
AS
SELECT
	c.courseName,
	s.subjectName,
	a.assignmentContent,
	sb.assignmentSubmitNum,
	cd.courseDetailNum,
	v.studentName,
	sb.assignmentExplain
FROM tblAssignmentSubmit sb
	INNER JOIN tblAssignment a
		ON a.assignmentNum = sb.assignmentNum
			INNER JOIN tblSubjectDetail sd
				ON a.subjectDetailNum = sd.subjectDetailNum
					INNER JOIN tblSubject s
						ON s.subjectNum = sd.subjectNum
							INNER JOIN tblCourseDetail cd
								ON cd.courseDetailNum = sd.courseDetailNum
									INNER JOIN tblCourse c
										ON c.courseNum = cd.courseNum
											INNER JOIN vwStudent v
												ON v.studentNum = sb.studentNum
													ORDER BY s.subjectName ASC;

--과제를 제출한 학생 명단 뷰 호출								
SELECT * FROM vwAssignmentSubmitStudentList;

프로젝트 후기

교육센터 관리 시스템을 ANSI-SQL, PL/SQL로 만들기까지 요구분석서 작성, 순서도, ERD(개념 모델링, 논리 다이어그램, 물리 다이어그램)을 팀원들과 함께 만들게 되었다. 컴퓨터를 하나 앞에 놓고 팀원들과 함께 요구분석서에 따라 구현될 시스템을 상상해보면서 테이블은 어떻게 분리하고, 다이어그램을 만들어야 할지를 함께 구상하면서 작업을 진행했는데, 이 과정에서 데이터를 관리하는데 어떻게 하는 게 더 효율적인지 다른 팀원들과 의견을 나누면서 내가 다르게 알고 있었던 것을 바로잡고 여러모로 많이 배울 수 있었다.

이번 프로젝트를 하면서 코드를 통합하는 업무를 맡게 되었고, 팀원들의 코드를 읽고 피드백하면서 나의 코드 또한 보완할 점이 많다는 것을 알게 되었다. 프로젝트를 진행하며 팀장의 역할이 무엇인지 고민하기도 하고, 프로젝트의 진행 척도와 균일한 업무 분담을 위한 방법을 계속 생각해보았다. 팀원으로 프로젝트를 진행할 때보다 힘들고 생각할 점도 많았지만, 배울 점을 더 많이 찾을 수 있었기 때문에 의미 있는 경험이었다고 생각한다.


팀장으로서의 후기

이번 오라클 프로젝트의 팀장에 임하면서 느낀 점 중의 하나는 팀장은 프로젝트의 전체적인 큰 그림을 그리고 있어야 한다는 것이었다. 프로젝트를 도중에 예상하지 못한 문제에 부딪혀 프로젝트가 지연될 때가 있었다. 프로젝트를 추진력 있게 진행하기 위해서 각 파트에 필요한 인원을 분배하고, ERD, 더미 데이터 생성, DDL 및 DML 통합, ANSI-SQL, PL/SQL 작성 등의 단계에 있어서 팀원들의 수행 능력과 각 단계에 할당할 수 있는 시간을 고민했던 거 같다.

이러한 나의 고민과는 별개로 팀원분들 모두 맡은 역할을 정말 열심히 참여해 주었다. SQL 쿼리를 작성하면서 DDL, DML에 대해 수정할 점이나 문제가 있을 때마다 공유하고, 소통하면서 시간을 절약하며 수월하게 프로젝트를 진행할 수 있었다. 가장 감사한 점은 팀원분들이 각자 맡은 업무를 하는데, 주도적으로 더 필요한 게 있으면 찾아서 만들고, 할 일을 마치면 다른 팀원들의 업무를 도와주었다는 점이다. 팀원분들이 모두 열심히 하셨기 때문에 나도 더 열심히 하고 싶었다. 그래서 프로젝트가 끝났을 때 후회가 없었고, 프로젝트의 완성도 또한 더욱 높아질 수 있었다고 생각한다.