C# WinForms + Oracle DB 기반의 기숙사 사생 및 외박/점호 통합 관리 시스템
기존 수기 및 엑셀 기반 관리 방식의 비효율을 해소하고, 기숙사 운영 전반을 하나의 시스템으로 통합 관리하기 위해 개발된 데이터베이스 프로그래밍 프로젝트입니다.
| 항목 | 내용 |
|---|---|
| 프로젝트명 | 삼육대학교 데이터베이스 프로그래밍 기숙사 관리 시스템 |
| 개발 기간 | 2025.11 ~ 2026.01 |
| 팀 구성 | 3인 (PM/UI, DB, 기획/QA) |
- 호실 카드 UI를 통한 직관적인 배정 현황 파악
- 외박 신청 및 점호 데이터의 실시간 연동
- 학기별 사생 이력의 체계적 관리
| 구분 | 기술 |
|---|---|
| Language | C# (.NET Framework 4.7.2) |
| UI | Windows Forms (WinForms) |
| Database | Oracle 11g Express Edition (XE) |
| DB 연동 | ODP.NET (Oracle Data Provider for .NET) |
| IDE | Visual Studio 2017+, Oracle SQL Developer |
Form1 (메인 셸)
├── 왼쪽 패널: 내비게이션 메뉴
└── 오른쪽 패널: UserControl 전환 영역
│
├─ [관리 업무]
│ ├── UC_Admin_Settings — 학기/기숙사동/호실/입사정보 관리
│ ├── UC_Student — 사생 등록 및 검색
│ ├── UC_Assignment_Status— 호실 카드 기반 배정 현황 조회
│ └── UC_Assignment_Manage— 사생 호실 배정 처리
│
└─ [사감 업무]
├── UC_Leave_Manage — 외박/점호면제 신청 등록
├── UC_RollCall_Process — 일일 점호 결과 입력
└── UC_RollCall_Stats — 점호 결과 통계 조회
DBClass ─── Oracle 11g XE (ODP.NET, 파라미터 바인딩)
Form1이 단일DBClass인스턴스를 생성하고, 각 UserControl에Init(dbc)메서드로 주입- 모든 SQL은
OracleParameter[]파라미터 바인딩 사용 - UserControl 간 독립적 개발이 가능한 구조로 Git 충돌 최소화
TabControl 기반으로 학기, 기숙사동, 호실, 입사 정보를 통합 관리합니다. 팝업 폼(FormTermPopup, FormDormitoryPopup, FormRoomPopup, FormResidencyPopup)을 통한 CRUD 처리.
사생의 기본 정보(학번, 이름, 성별, 학과, 연락처) 등록/수정/검색 및 상세 이력 조회(Form2).
각 호실을 카드 형태(UC_RoomCard)로 시각화하여 현재 배정 인원과 공실 여부를 확인합니다.
| 색상 | 상태 |
|---|---|
| 회색 | 재실 (Present) |
| 노란색 | 외박 (Leave) |
| 빨간색 | 미귀가 (Absent) |
| 초록색 | 면제 (Exempted) |
기숙사동/학기 기준으로 사생을 호실에 배정하거나 배정을 해제합니다.
기숙사동별 사생 목록을 조회하고, 외박 또는 점호면제 신청을 등록/삭제합니다.
날짜 및 기숙사동을 선택하여 해당일의 점호 결과(출석/미귀가)를 일괄 입력합니다. 외박/면제 대상자는 자동으로 표시됩니다.
날짜 범위, 기숙사동, 사생명 기준으로 점호 이력을 조회하고 통계를 확인합니다.
| 테이블 | 설명 |
|---|---|
Student |
사생 기본 정보 |
AcademicTerm |
학기 정보 (연도, 학기코드, 기간) |
Dormitory |
기숙사동 정보 |
Room |
호실 정보 (호실번호, 정원, 소속 동) |
StudentTermResidency |
학기별 사생 입사 기록 |
RoomAssignment |
사생-호실 배정 기록 |
DailyLeaveExemption |
외박/점호면제 신청 기록 |
Attendance |
일일 점호 결과 기록 |
Student ──┬── StudentTermResidency ── RoomAssignment ── Room ── Dormitory
├── DailyLeaveExemption
└── Attendance
- 정규화를 통한 데이터 중복 최소화
- PK/FK 제약 조건으로 참조 무결성 보장
- 호실 정원 초과 방지 등 비즈니스 규칙 적용
- Oracle 11g XE 설치 및 실행 (localhost:1521, service_name: xe)
- ODP.NET (Oracle.DataAccess.dll) 설치
- .NET Framework 4.7.2 이상
- DB 스키마 및 테이블 사전 생성
# Visual Studio에서 솔루션 열기
SYU-DBP-DMS-1.1.sln
# 또는 커맨드라인 빌드
msbuild SYU-DBP-DMS-1.1.sln /p:Configuration=Debug
# 실행
SYU-DBP-DMS-1.1\bin\Debug\SYU-DBP-DMS-1.1.exeDBClass.cs의 connectionString 필드를 환경에 맞게 수정:
string connectionString = "User Id=<사용자>; Password=<비밀번호>; Data Source=...";검토일: 2026-02-02 검토 대상: 전체 소스 파일 15개 발견 이슈: 총 28건 (CRITICAL 5건, HIGH 8건, MEDIUM 9건, LOW 6건)
| 심각도 | 건수 | 설명 |
|---|---|---|
| CRITICAL | 5 | 즉시 수정 필요 (보안 취약점, 데이터 무결성) |
| HIGH | 8 | 배포 전 수정 필요 (리소스 누수, 오류 처리) |
| MEDIUM | 9 | 가능한 빨리 수정 (코드 품질, 입력 검증) |
| LOW | 6 | 개선 권장 (가독성, 유지보수성) |
- 위치:
DBClass.cs14행 - 내용: 연결 문자열에 사용자 ID(
hong1)와 비밀번호(1111)가 소스 코드에 평문으로 노출되어 있으며, Git 히스토리에 영구 기록됨 - 영향: 저장소 접근 권한이 있는 누구나 DB에 직접 접근 가능
- 권장: 연결 문자열을
App.config또는 환경 변수로 분리, 비밀번호 강화, Git 히스토리에서 자격증명 제거
- 위치:
FormResidencyPopup.cs142~171행 - 내용: 프로젝트 내 유일하게 매개변수화되지 않은 SQL 쿼리 사용. INSERT/UPDATE에서 문자열 보간(
$"")으로 사용자 입력(type,note)을 직접 SQL에 삽입
// 취약한 코드 예시
string sql = $@"INSERT INTO StudentTermResidency (...)
VALUES ({newId}, {_studentId}, {termId}, '{type}',
TO_DATE('{date}','YYYY-MM-DD'), '{note}', SYSDATE)";- 영향:
note필드에'); DELETE FROM StudentTermResidency; --같은 입력으로 데이터 전체 삭제 가능 - 권장: 다른 파일들과 동일하게
OracleParameter[]매개변수화 쿼리로 전환
- 위치:
UC_Student.cs220~226행 - 내용: 학생 삭제 시 5개 테이블에서 순차 DELETE를 수행하지만, 트랜잭션으로 감싸지 않음
삭제 순서: RoomAssignment → StudentTermResidency → DailyLeaveExemption → Attendance → Student
- 영향: 중간 실패 시 일부만 삭제되어 데이터 정합성 파괴, 복구 불가
- 권장:
OracleTransaction사용하여 원자적 실행 보장
- 위치: 7개 파일에서 동일 패턴 사용 (
UC_Student.cs,UC_Assignment_Manage.cs,UC_Leave_Manage.cs,UC_RollCall_Process.cs,FormDormitoryPopup.cs,FormRoomPopup.cs,FormResidencyPopup.cs) - 내용:
SELECT NVL(MAX(Id), 0) + 1패턴으로 ID 채번 시, SELECT와 INSERT 사이에 다른 세션이 동일 ID를 획득 가능 - 영향: 동시 사용 시 Primary Key 충돌, 데이터 유실
- 권장: Oracle Sequence 도입 (
CREATE SEQUENCE ... START WITH 1 INCREMENT BY 1)
- 위치:
DBClass.cs65행, 96행 - 내용: 오류 발생 시 SQL 쿼리 전문이
MessageBox로 사용자에게 노출됨
MessageBox.Show("DML 수행 오류: " + ex.Message + "\nSQL: " + sql);- 영향: 테이블명, 컬럼명, 쿼리 구조 등 DB 스키마 정보 유출
- 권장: 사용자에게는 일반적 오류 메시지만 표시, 상세 내용은 로그 파일에 기록
- 위치:
Form2.cs13행,FormDormitoryPopup.cs10행,FormRoomPopup.cs10행,FormResidencyPopup.cs9행 - 내용: 팝업 폼들이 각각 독립적인
DBClass인스턴스를 생성하고DB_Open()을 호출하지만, 폼 종료 시DB_Close()를 호출하지 않음 - 영향: 팝업 열 때마다 Oracle 연결 누수, 장시간 사용 시
ORA-12516오류 가능 - 권장: 폼 생성자에서 공유
DBClass주입 받거나,FormClosing에서DB_Close()호출
- 위치:
DBClass.cs전체 - 내용:
OracleConnection비관리 리소스를 보유하지만IDisposable패턴이 없어using문으로 안전하게 해제 불가 - 권장:
IDisposable구현 및Dispose(bool disposing)패턴 적용
- 위치:
DBClass.cs11행 - 내용:
public OracleConnection conn으로 선언되어 외부에서 직접 접근 가능. 실제로Form2.cs에서dbc.conn을 직접 사용하여DBClass래퍼를 우회 - 권장:
private으로 변경하고, 필요한 기능은DBClass메서드로 래핑
- 위치:
UC_RollCall_Process.cs127~209행 - 내용: 전체 학생의 점호 결과를 개별 쿼리로 저장하되 트랜잭션 없음. N명 중 K번째에서 오류 시 부분 저장 발생
- 권장: 전체 저장을 트랜잭션으로 감싸고,
MERGE INTOUPSERT 구문 활용 검토
- 위치:
UC_Assignment_Manage.cs211~263행 - 내용: 입사이력 조회 → 중복 확인 → INSERT 3단계가 트랜잭션 없이 수행. 중복 확인과 INSERT 사이에 다른 세션이 동일 배정 가능
- 권장:
SELECT FOR UPDATE또는 DB 레벨 UNIQUE 제약으로 동시성 제어
- 위치:
UC_Assignment_Manage.cs211~263행 - 내용: 배정 시 해당 호실의 현재 인원이 정원(capacity)을 초과하는지 DB에서 검증하지 않음. UI 빈 자리 버튼에만 의존
- 권장: INSERT 전 현재 배정 인원과 정원 비교 검증, DB 트리거 또는 CHECK 제약 추가
- 위치:
Form2.cs전체 - 내용:
OnLoad에서dbc.DB_Open()호출하지만 폼 종료 시DB_Close()누락 - 권장:
FormClosing이벤트에dbc.DB_Close()추가
- 위치:
UC_Admin_Settings.cs211행,UC_RollCall_Stats.cs47행 - 내용:
catch { }블록에서 예외를 완전히 무시하여 오류 원인 추적 불가 - 권장: 최소한 로그 기록 후 사용자에게 적절한 메시지 표시
- 위치:
UC_Admin_Settings.cs,UC_Assignment_Status.cs,UC_Assignment_Manage.cs,UC_Leave_Manage.cs,UC_RollCall_Process.cs,UC_RollCall_Stats.cs,FormRoomPopup.cs - 내용: 동일한 기숙사 콤보박스 로딩 로직이 7곳에서 중복 구현
- 권장: 공통 헬퍼 클래스로 추출하여 DRY 원칙 준수
- 위치:
DBClass.cs17~31행 - 내용: 연결 실패 시
MessageBox만 표시하고 예외를 삼킴. 팝업 폼에서는 연결 상태 확인 없이 바로 쿼리 실행 - 권장:
bool반환값 또는 예외 재발생으로 호출자에게 실패 전달
- 위치:
Form1.cs111행, 128행 - 내용: 일부 UC 접근에만 null 체크가 있고 다른 곳에는 없음 (
uc_Assignment_Status1.RefreshData()vsif (uc_Assignment_Manage1 != null)) - 권장: 모든 UC 접근에 일관된 null 체크 적용
- 위치:
DBClass.cs90~101행 - 내용:
finally블록에서Close()만 호출하고Dispose()미호출 - 권장:
using문 패턴으로 변경
- 위치:
UC_Assignment_Status.cs99행,UC_Assignment_Manage.cs156행 - 내용:
dtOccupants.Select($"RoomId = {roomId}")— DB 값이라 직접 위험은 낮으나 특수문자 시EvaluateException가능 - 권장: LINQ 또는 반복문 필터링으로 대체
- 위치:
Form2.cs8행 - 내용:
Form2만SYU_DBP_DMS_1._1네임스페이스 사용 (나머지 전체:SYU_DBP_DMS_1_1) - 권장:
SYU_DBP_DMS_1_1로 통일
- 위치:
UC_Student.cs6281행, 132207행 - 내용: 학번(자릿수/숫자 여부), 전화번호(형식), 이름(길이) 등에 대한 형식 검증 없음
- 권장: 정규식 검증 및
MaxLength속성 설정
- 위치:
UC_Leave_Manage.cs132~182행 - 내용: 사유가 빈 문자열이어도 저장 가능, 과거/미래 날짜 범위 제한 없음
- 권장: 사유 필수 입력 및 날짜 범위 검증 추가
- 위치:
DBClass.cs전체 설계 - 내용: 앱 시작~종료까지 하나의 연결을 유지하며 네트워크 단절/DB 재시작 시 복구 메커니즘 없음
- 권장: 연결 풀링 활용 또는 작업 시 연결 상태 확인/재연결 로직 추가
- 내용: 상태값(
"입사","출석","미귀가","외박","면제"등)이 코드 전체에 문자열 리터럴로 산재 - 권장: 상수 클래스 또는 Enum으로 중앙 관리
- 위치:
Form2.cs248~261행 - 내용:
label3,label4,label5등 기본 이름 사용으로 가독성 저하 - 권장:
lblLeaveCount,lblAttendanceRate등 의미 있는 이름으로 변경
- 위치:
Form1.cs2~8행 - 내용:
System.Linq,System.Threading.Tasks등 미사용 네임스페이스 포함 - 권장: IDE의 "Remove Unused Usings" 기능으로 정리
- 위치:
UC_RoomCard.cs7480행,233행UC_RollCall_Process.cs229 - 내용: 동일 상태에 대해 다른 색상 사용 (미귀가:
Color.RedvsColor.MistyRose) - 권장: 공통 색상 매핑 유틸리티로 추출하여 일관성 유지
- 위치:
UC_RollCall_Stats.cs125행 - 내용:
외박신청내역ToolStripMenuItem_Click— 메서드명에 한글 포함 - 권장:
tsmiLeaveHistory_Click등 영어 네이밍으로 통일
- 위치:
UC_Admin_Settings.cs113~124행 - 내용: 학기 삭제 시 연관된
StudentTermResidency존재 여부를 사전 확인하지 않음 - 권장: 삭제 전 연관 데이터 수를 조회하여 사용자에게 경고 메시지 표시
| 순위 | 조치 항목 | 관련 이슈 |
|---|---|---|
| 1 | FormResidencyPopup.cs SQL Injection 수정 (매개변수화 쿼리 적용) |
C-02 |
| 2 | DB 자격증명을 App.config로 분리, 비밀번호 강화 |
C-01 |
| 3 | Oracle Sequence 도입으로 MAX+1 패턴 제거 | C-04 |
| 4 | DBClass에 트랜잭션 지원 추가 (BeginTransaction/Commit/Rollback) |
C-03, H-04, H-05 |
| 5 | DBClass에 IDisposable 구현, 팝업 폼 연결 누수 수정 |
H-01, H-02, H-07 |
| 6 | 오류 메시지에서 SQL 쿼리 제거, 로깅 시스템 도입 | C-05, H-08 |
| 7 | conn 필드를 private으로 변경 |
H-03 |
| 8 | 호실 정원 검증 로직 추가 | H-06 |
| 9 | 입력값 검증 강화 (학번, 전화번호 형식 등) | M-07, M-08 |
| 10 | 공통 로직 추출 (콤보 로딩, 색상 매핑) 및 매직 스트링 제거 | M-01, L-01, L-04 |