다음 함수를 만들었으며 Gradepoint에서 사용 된 척도를 기반으로 한 평균 점수로 학생 테이블의 이름을 쿼리하고 싶습니다. 어떤 아이디어? 아래에 내 학생, 수업 및 성적표를 결합하는 선택 진술을 제공했습니다.
DECLARE
FUNCTION GradePoint(GRADE varchar2)
return number
is
BEGIN
RETURN CASE grade
when 'A+' then 9
when 'A' then 8
when 'A-' then 7
when 'B+' then 6
when 'B' then 5
when 'B-' then 4
when 'C+' then 3
when 'C' then 2
when 'D'then 1
when 'F'then 0
else -1
END;
END;
SELECT student.student_id, student.first_name, student.last_name, avg(gradepoint(class.grade))
FROM CLASS
JOIN STUDENT
ON student.student_id = class.student_id
JOIN course
ON course.course_id = class.course_id
group by 1;
@SayanMalakshinov는 함수 정의를 인라인 할 수 있음을 나타 내기 때문에 단일 쿼리 내에서만 함수를 사용할 수 있고 정확히 필요한 경우 매우 많은 경우에 유용합니다. 그러나 일반적으로 사용할 수 있으려면 저장 프로 시저 (프로 시저의 일반)를 만들어야합니다. 이를 위해서는 먼저 PLSQL의 블록 구조를 이해해야합니다. PLSQL 프로 시저에는 익명 블록과 명명 된 블록의 두 가지 주요 변형이 있습니다. 둘 다 최대 3 개 섹션 (선언, 실행 및 예외 섹션)으로 일관됩니다. 익명 블록의 경우 선언 및 예외 섹션은 선택 사항입니다. 그런 다음 전체 블록이 END 문으로 종료되었습니다.
declare -- Declaration section
-- contains local definitions
begin -- Execution section
-- contains the code
exception -- Exception Section
when ... -- contains code to handle specific exceptions
when ... -- that occur within the execution section
end; -- Block terminates
명명 된 블록은 선언 섹션도 필요하다는 점을 제외하면 동일한 구조를 갖지만 DECLARE로 시작하는 대신 FUNCTION 또는 PROCEDURE로 시작합니다. 마지막으로 블록은 중첩 될 수 있습니다. 블록은 내부에 정의되고 다른 블록이 정의됩니다. 외부 블록에 정의 된 모든 것은 중첩 된 블록에서 사용할 수 있습니다. 일부 제한 사항이있는 경우 명명 된 블록은 익명 블록에 중첩 될 수 있습니다 (선언 섹션에서). 그리고 익명 블록 내의 다른 정의와 마찬가지로 블록이 종료되면 명명 된 블록의 정의가 범위를 벗어납니다.
이제 코드를 살펴보십시오.
declare
function GradePoint(GRADE varchar2)
...
end;
end;
마지막은 다음과 같습니다. 명명 된 블록 GradePoint가 익명 블록에 중첩됩니다. 일반 가용성을 위해 DECLARE를 컴파일러 지시문 CREATE로 대체하십시오. 그래서:
create or replace
function GradePoint(grade varchar2)
...
select ...
, case ...
end;
end GradePoint;
귀하의 최종 쿼리에 관해서는 귀하가 원하는 평균이 무엇인지 혼란 스러웠습니다. 설명은 전체 성적 포인트를 의미하지만 초기 쿼리는 학생 별 점수를 의미합니다. 어느 쪽이든 avg 함수의 창 버전은 적절한 값을 얻습니다. 다음과 같이 시도하십시오.
select distinct
s.student_id
, s.first_name
, s.last_name
, round(avg(GradePoint(cl.grade)) over (partition by s.student_id),2) gpa
, round(avg(GradePoint(cl.grade)) over (),2) overall_gpa
from student s
join class cl on cl.student_id = s.student_id
join course c on c.course_id = cl.course_id
order by s.student_id;
참고 : CamelCase 이름은 피해야합니다. 내부적으로 Oracle은이를 대문자로 변환합니다 (모든 객체 유형 테이블, 열, 뷰, 프로 시저, ,,, 모든 명명 된 객체. 참조하는 모든 참조는 대문자 값을 사용합니다. 따라서 GradePoint는 항상 GRADEPOINT로 표시됩니다. Oracle에서는 더 좋습니다. Snake_Case 규칙을 사용합니다. 예, 대문자로 표시되지만 읽기가 더 쉽습니다. 항목이 밀접하게 명명 될 때 특히 더 큰 이해와 오류 감소를 의미합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다