데이터베이스 프로그래밍 과제 / 최신 데이터베이스

2025. 6. 11. 10:42·database
DECLARE
    sum1 NUMBER := 0;
    CURSOR dept_cnt IS SELECT deptno, dname FROM DEPT;
BEGIN
    FOR dept IN dept_cnt LOOP
        IF(mod(dept.deptno,4) = 0) THEN
            sum1 := sum1 + dept.deptno;
        END IF;
        DBMS_OUTPUT.put('부서번호 : ' || TO_CHAR(dept.deptno));
        DBMS_OUTPUT.PUT_LINE('부서이름 : ' || dept.dname);
        
    END LOOP;
    DBMS_OUTPUT.put_line('4의 배수인 부서번호의 합계: ' || TO_CHAR(sum1));
END;
CREATE or replace TRIGGER sal_trigger
 BEFORE
 INSERT OR UPDATE
 ON EMP
 FOR EACH ROW
DECLARE
    disable_sal EXCEPTION;
BEGIN
    IF :new.sal < 10 THEN
        RAISE disable_sal;
    END IF;
 EXCEPTION
    WHEN disable_sal THEN 
        RAISE_APPLICATION_ERROR(-20500, '급여 부족');
END;

 

/*
여러 행을 반환하는 select문은 cursor를 이용해야 할 것 같아서 자료를 보고 따라하는데 프로시저는 DECLARE를
하지 않아서 계속 문법오류가 나서 오래 걸렸다. 프로시저의 IS에 같이 선언하면 된다.
*/
CREATE OR REPLACE PROCEDURE SelectTimeTable(sStudentId IN CHAR, -- 학번
					    nYear      IN NUMBER,-- 학년도
					    nSemester  IN NUMBER) -- 학기 					
IS 
  sId				COURSE.C_ID%TYPE; -- 과목번호
  sName				COURSE.C_NAME%TYPE; -- 과목명
  nUnit				COURSE.C_UNIT%TYPE; -- 학점
  nTime				TEACH.T_TIME%TYPE; -- 교시
  sWhere			TEACH.T_WHERE%TYPE; -- 강의실
  nTotUnit			NUMBER := 0; -- 총학점
 
 CURSOR course_all is
 SELECT e.c_id, c.c_name, c.c_unit, t.t_time, t.t_where
         -- 과목번호,  과목명,   학점,     교시,    강의실
  FROM enroll e, course c, teach t
  WHERE  e.c_id = c.c_id and  e.c_id = t.c_id and
               e.s_id = sStudentId and e.e_year = nYear and e.e_semester=nSemester and
               t.t_year = nYear  and t.t_semester = nSemester            
  ORDER BY 4; 

BEGIN

  OPEN course_all;
  DBMS_OUTPUT.put_line('<수강신청 시간표>');
  DBMS_OUTPUT.put_line('학번:' || sStudentId);               
  DBMS_OUTPUT.put_line('년도:' || TO_CHAR(nYear)); 
  DBMS_OUTPUT.put_line('학기:' || TO_CHAR(nSemester));                 
                  
  
  LOOP
     FETCH course_all INTO sId, sName, nUnit, nTime, sWhere;
     EXIT WHEN course_all%NOTFOUND;
     DBMS_OUTPUT.put_line('교시:' || TO_CHAR(nTime) ||
                          ', 과목번호:' || sID || 
			  ', 과목명:'|| sName ||	
			  ', 학점:' || TO_CHAR(nUnit) ||			  
			  ', 강의실:' || sWhere);
     nTotUnit := nTotUnit + nUnit;
        -- 학점 합계 구하기(nUnit 변수를 이용하여, nTotUnit 변수에 총합 저장)

  END LOOP;

  DBMS_OUTPUT.put_line('총 ' || TO_CHAR(course_all%ROWCOUNT) || ' 과목과 총 ' ||
                        TO_CHAR(nTotUnit) || '학점을 신청하였습니다.');

  CLOSE course_all;
      
END;
CREATE OR REPLACE FUNCTION Date2EnrollYear(dDate IN DATE)
RETURN NUMBER
IS
  nYear				NUMBER;
  sMonth			CHAR(2);

BEGIN

/* 10월 ~ 12월 : 매개변수로 받은 날짜의 다음 년도, 10월~12월 외 : 매개변수로 받은 날짜의 년도 */
  nYear  := EXTRACT(YEAR FROM dDate); -- 매개변수로 받은 날짜 중 '년도' 추출
  sMonth := TO_CHAR(EXTRACT(MONTH FROM dDate));  -- 매개변수로 받은 날짜 중 '월' 추출  

  IF (sMonth='10' or sMonth='11' or sMonth='12')  THEN
     nYear := nYear + 1;
  END IF; 
  
  RETURN nYear;
END;

CREATE OR REPLACE FUNCTION Date2EnrollSemester(dDate IN DATE)
RETURN NUMBER
IS
  nSemester			NUMBER;
  sMonth			CHAR(2);

BEGIN

/* 10월 ~ 12월 : 매개변수로 받은 날짜의 다음 년도, 10월~12월 외 : 매개변수로 받은 날짜의 년도 */
  sMonth := TO_CHAR(EXTRACT(MONTH FROM dDate));  -- 매개변수로 받은 날짜 중 '월' 추출  

  IF (sMonth='10' or sMonth='11' or sMonth='12' or sMonth='1' or sMonth='2' or sMonth='3')  THEN
     nSemester := 1;
  ELSE
     nSemester := 2;
  END IF; 
  
  RETURN nSemester;
END;
CREATE OR REPLACE PROCEDURE InsertEnroll(sStudentId IN CHAR, -- 학번
				sCourseId IN CHAR,  -- 과목번호
				result	OUT VARCHAR2) -- 입력 결과 메시지
IS
  too_many_sumCourseUnit	EXCEPTION;
  too_many_courses		EXCEPTION;
  too_many_students		EXCEPTION;
  duplicate_time		EXCEPTION;
  nYear				NUMBER;  -- 수강신청 년도
  nSemester			NUMBER;  -- 수강신청 학기
  nSumCourseUnit		NUMBER;  -- 수강신청완료된 과목들의 총학점
  nCourseUnit			NUMBER;  -- 학점 
  nCnt				NUMBER;  
  nTeachMax			NUMBER;  -- (수강신청 년도,학기,과목에 대한) 최대 학생수(최대 정원)

BEGIN
  result := '';

  DBMS_OUTPUT.put_line('#');
  DBMS_OUTPUT.put_line(sStudentId || '님이 과목번호 ' || sCourseId || '의 수강 등록을 요청하였습니다.');

  /* (수강신청하는 오늘 날짜를 기준으로) 수강신청 년도, 학기 알아내기 : 함수 사용 */   
  nYear := Date2EnrollYear(SYSDATE);  -- 수강신청 년도
  nSemester := Date2EnrollSemester(SYSDATE);   -- 수강신청 학기


  /* 에러 처리 1 : 최대학점(18학점) 초과 여부 검사 */
  -- (수강신청 년도, 학기에 해당 학생의) 수강신청 완료(enroll 테이블에 저장 완료)된 과목들의 총학점
  SELECT SUM(c.c_unit) 
  INTO	 nSumCourseUnit
  FROM   course c, enroll e
  WHERE  e.s_id = sStudentId and e.e_year = nYear and e.e_semester = nSemester
	and  e.c_id = c.c_id;

  -- 현재 수강신청을 하려고 하는 과목의 학점을 검색하여 nCourseUnit 변수에 저장
  SELECT c_unit
  INTO	 nCourseUnit
  FROM   course
  WHERE  c_id = sCourseId;

  -- 수강신청 완료된 과목들의 총학점 + 현재 수강신청을 하려고 하는 과목의 학점 > 18인지 검사
  IF (nSumCourseUnit + nCourseUnit > 18) THEN
      RAISE too_many_sumCourseUnit;
  END IF;


  /* 에러 처리 2 : 동일한 과목 신청 여부 검사 */
  -- 해당 학생의 수강신청 완료(enroll 테이블에 저장 완료)된 과목 중, 현재 수강신청을 하려고 하는 과목이 있는지 검사
  SELECT COUNT(*)
  INTO	 nCnt
  FROM   enroll
  WHERE  s_id = sStudentId and c_id = sCourseId;

  IF (nCnt > 0) 
  THEN
     RAISE too_many_courses;
  END IF;


  /* 에러 처리 3 : 수강신청 인원 초과 여부 검사 */
  -- (수강신청 년도,학기,과목에 대한) 최대 학생수(최대 정원) 검색
  SELECT t_max
  INTO	 nTeachMax
  FROM   teach
  WHERE  t_year= nYear and t_semester = nSemester and c_id = sCourseId;


  -- (수강신청 년도,학기,과목으로) 이미 수강신청 완료(enroll 테이블에 저장 완료)된 학생수 검색하여 nCnt 변수에 저장
  SELECT COUNT(*)
  INTO	 nCnt
  FROM   enroll
  WHERE  e_year = nYear and e_semester = nSemester and c_id = sCourseId;

  -- (수강신청 년도,학기,과목에 대한) 수강신청 완료 학생수 >= (수강신청 년도,학기,과목에 대한)최대 학생수 인지 검사
  IF (nCnt >= nTeachMax)
  THEN
     RAISE too_many_students;
  END IF;


  /* 에러 처리 4 : 신청한 과목들 시간 중복 여부  */  
  -- (수강신청 년도,학기에) 수강신청하려고 하는 과목의 교시(수업시간)와
  -- (수강신청 학생,년도,학기로) 이미 수강신청 완료된 과목들의 교시(수업시간)
  -- 중 중복되는 교시(수업시간)가 있는지 검사
  SELECT COUNT(*) 
  INTO   nCnt
  FROM
  (
	  SELECT t_time
	  FROM teach
	  WHERE t_year=nYear and t_semester = nSemester and c_id = sCourseId 
	  INTERSECT
	  SELECT t.t_time
	  FROM	teach t, enroll e
	  WHERE	e.s_id=sStudentId and e.e_year=nYear and e.e_semester = nSemester and
		t.t_year=nYear and t.t_semester = nSemester and	
        e.c_id=t.c_id
  );
  
  IF (nCnt > 0)
  THEN
     RAISE duplicate_time;
  END IF;


  /* 수강 신청 : Enroll 테이블에 학번,과목번호,수강년도, 수강학기 입력 */
  INSERT INTO enroll VALUES(sStudentId, sCourseId, nYear, nSemester);

  COMMIT;
  result := '수강신청 등록이 완료되었습니다.';

EXCEPTION
  WHEN too_many_sumCourseUnit THEN
    result := '최대학점을 초과하였습니다';
  WHEN too_many_courses THEN
    result := '이미 등록된 과목을 신청하였습니다';
  WHEN too_many_students THEN
    result := '수강신청 인원이 초과되어 등록이 불가능합니다';
  WHEN duplicate_time THEN
    result := '이미 등록된 과목 중 중복되는 시간이 존재합니다';
  WHEN OTHERS THEN        
        result := SQLCODE;

END;
CREATE or REPLACE TRIGGER BeforeUpdateStudent
BEFORE UPDATE ON student
FOR EACH ROW

DECLARE
  underflow_length  EXCEPTION;
  invalid_value     EXCEPTION;
  nLength			NUMBER;
  nBlank			NUMBER;

BEGIN
/* 암호 제약조건 : 4자리 이상, blank는 허용안함 */
 /* 오라클 내장함수 
     length(문자열) => 문자열의 길이 
     instr(문자열1, 문자열2) => 문자열1에서 문자열2가 나타난 첫번째 위치
 */

  nLength := length(:new.s_pwd);
  nBlank := instr(:new.s_pwd , ' ');
  
  IF nLength < 4 THEN
     RAISE underflow_length;
  ELSIF (nBlank > 0) THEN
     RAISE invalid_value;
  END IF;

  EXCEPTION
    WHEN underflow_length THEN
       RAISE_APPLICATION_ERROR(-20002, '암호는 4자리 이상이어야 합니다');
    WHEN invalid_value THEN
       RAISE_APPLICATION_ERROR(-20003, '암호에 공란은 입력되지 않습니다.');
END;

 

빅데이터

좁은 정의: 대규모 데이터

넓은 정의: 대규모 데이터를 저장 및 관리하는 기술과 가치있는 정보를 만들기 위해 분석하는 기술까지 포함

 

빅데이터 특징 5V

  • Volume(규모) : 증가된 데이터양
  • Variety(다양성) : 데이터 형태의 다양성
  • Velocity(속도) : 빨라진 데이터의 생성 속도
  • Value(가치) : 데이터의 가치
  • Veracity(정확성) : 데이터의 정확성

NoSQL: 빠른 속도로 생성되는 대량의 비정형 데이터를 저장하고 처리하기 위해 ACID(원자성, 일관성, 격리성, 지속성)를 위한 트랜잭션 기능을 제공하지 않는 대신, 저렴한 비용으로 여러대의 컴퓨터에 데이터를 분산∙저장∙처리하는 것이 가능한 데이터베이스

장점: 유연성(변경이 자유로움), 확장성(서버 추가 용이,클러스터), 경제성(오픈 소스)

 

NoSQL 종류

  • 키-값(key-value) 데이터베이스: 레디스(Redis), 다이나모(Dynamo)
    • 키와값의쌍으로데이터가저장됨
    • 질의처리속도빠름
    • 키를사용해서만검색(값을사용한검색안됨)
  • 문서기반(document-based) 데이터베이스: 몽고DB(MongoDB), 카우치DB(CouchDB)
    • 키와문서의쌍으로데이터를저장
    • 트리형태의계층적구조가존재하는 JSON, XML 등과같은반정형 (semi-structured) 데이터 형태로 트리 형태의계층적구조
  • 컬럼기반(column-based) 데이터베이스: 카산드라(Cassandra), HBase
    • 컬럼패밀리는관련있는컬럼값들을모아서구성
  • 그래프기반(graph-based) 데이터베이스: Neo4j
    • 데이터를데이터간의관계와함께표현
    • 질의는그래프순회과정을통해처리
    • SNS 에서친구찾기질의등을수행하는데적합

 

Mongo DB

데이터 구조: 데이터베이스 안에 컬렉션, 컬렉션 안에 문서가 포함된 계층적 구조

  • 문서(document)
    • { 필드이름: 필드값}
    • JSON(JavaScript Object Notation) 타입을 바탕으로 함
  • 컬렉션(collection)
    • 문서들의 모임
    • 같은 컬렉션 안에 저장되는 문서 구조가 다양할 수 있음
db.createCollection(“회원”)   // 컬렉션 생성(컬렉션 이름: 회원)
 db.회원.InsertMany( [
 {_id:1, 회원이름:"홍길동", 비밀번호:11, 나이:23, 성별:"남"},
 {_id:2, 비밀번호:23, 나이:25, 성별:"여",  직업:"유투버"}
 ])                                                                                                                      
db.회원.find({나이:23})                                                                                 
// 문서 삽입
// 문서검색
db.회원.updateMany({성별:"남"}, {$set:{성별:"M", 비밀번호:0}})  // 문서수정
db.회원.deleteMany({나이 : 23})                                                                  
db.회원.drop()                        
// 컬렉션삭제(컬렉션‘회원’삭제

 

벡터 데이터베이스: 비정형데이터를수치적표현인벡터(벡터임베딩 이라고도함) 형태로정보를저장하여다양한분석 및처리작업을수행하는데이터베이스, SQL이아닌, 벡터유사도를기반으로데이터검색

 

벡터 임베딩

  • 비정형데이터를고차원수치벡터로변환하는기술
  • 임베딩모델이자동생성

'database' 카테고리의 다른 글

SQL 문법 정리  (0) 2025.06.13
데이터베이스 개념  (0) 2025.06.13
데이터베이스 성능 향상[Index]  (0) 2025.06.11
Transaction(트랜잭션)  (0) 2025.06.11
PL/SQL (프로시저, 함수, 트리거)  (0) 2025.06.11
'database' 카테고리의 다른 글
  • SQL 문법 정리
  • 데이터베이스 개념
  • 데이터베이스 성능 향상[Index]
  • Transaction(트랜잭션)
chanhuy
chanhuy
  • chanhuy
    차늬
    chanhuy
  • 전체
    오늘
    어제
    • 분류 전체보기 (34)
      • algorithm (9)
      • Python (2)
      • database (8)
      • csts (3)
      • Operating System (0)
      • 오픈소스SW (1)
      • Git & Github (4)
      • 프로젝트 회고 (3)
      • 정보처리기사 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    recursion
    pl/sql
    오픈소스SW
    index
    graph algorithms
    Python
    Reduction
    backtracking
    dynamic programming
    COMMIT
    algorithm
    시간복잡도
    greedy
    프로젝트후기
    알고리즘
    Git
    D&C
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
chanhuy
데이터베이스 프로그래밍 과제 / 최신 데이터베이스
상단으로

티스토리툴바