2011-12-07 2 views
0

다음 코드는 나에게 좋지만 한 지점으로 작동합니다. 이 기능은 시험 성적에 따라 학생의 학년 수준을 표시해야하지만 나머지 두 문장을 실행하지 않으므로 학생의 점수가 50 점 미만인 경우 기능에 "통과"가 계속 표시됩니다.코드가 점에 작동합니다.

CREATE OR REPLACE FUNCTION stud_Result(integer,numeric) RETURNS text 
AS 
$$ 
DECLARE 
    stuNum ALIAS FOR $1; 
    grade ALIAS FOR $2; 
    result TEXT; 
BEGIN 
    IF grade >= 70.0 THEN SELECT 'distinction' INTO result FROM student,entry 
     WHERE student.sno = entry.sno AND student.sno = stuNum; 

    ELSIF grade >=50.0 OR grade <=70.0 THEN SELECT 'pass' INTO result FROM student,entry 
     WHERE student.sno = entry.sno AND student.sno = stuNum; 

    ELSIF grade >0 OR grade< 50.0 THEN SELECT 'fail' INTO result FROM student,entry 
     WHERE student.sno = entry.sno AND student.sno = stuNum; 

    ELSE SELECT 'NOT TAKEN' INTO result FROM student,entry 
     WHERE student.sno = entry.sno AND student.sno = stuNum; 
    END IF; 

    RETURN result; 
END;$$ 
LANGUAGE PLPGSQL; 

누구든지 문제를 지적 할 수 있습니까?

+0

내가 너라면, 첫 번째 t 내가 시도 할 수있는 힌지는 더 작은 * 기능이 될 것이다. 아무 것도하지 않는 사람을 만드십시오. 그런 다음 (a) 함수를 만드는 데 문제가 있거나 (b) 작성한 함수에 문제가 있는지 여부를 알 수 있습니다. –

답변

1

이것은 PostgreSQL의 잡아 넘어서 저를 위로했습니다. ELSE IFELSIF으로 대체해야합니다.

연속적으로 각각 ELSE IF이 중첩 된 IF 블록을 시작하는 것으로 해석되므로 자체 오류 END IF;이 표시됩니다.

은 올바른 구문에 대한 자세한 내용은 the documentation on conditionals를 참조하십시오.

0

조건부의 논리가 조금 이상합니다. 당신이 가지고 : 당신이 그 지점에서 원하지 않는 다른 값을 많이 할로 만족에게 두 번째 조건을 제로

  • grade > 0 OR grade < 50.0
    • grade >= 70.0
    • grade >= 50.0 OR grade <= 70.0
    • 조건.

      • grade >= 70.0
      • grade >= 50.0 AND grade <= 70.0
      • grade > 0 AND grade < 50.0

      당신은 또한 사람이 과정에 있는지 확인하기 위해에 select를 사용하는 것 같다하지만 grade 경우 주어진다 : 난 당신이 원하는 생각 그리고 그들은 코스에 없다면, 당신은 NULL result으로 끝날 것입니다. "in the course"확인이 함수 외부에 있거나 반환하기 전에 NULL result'NOT TAKEN'으로 변환해야합니다.

      이것은 숙제처럼 보입니다. 그래서 나는 이것보다 더 이상 명확하지 않을 것입니다.

    +0

    도움을 많이 주셔서 고맙습니다. –

    0

    일반적으로 코드에서 데이터를 숨기는 것이 좋습니다.

    SET search_path='tmp'; 
    
    -- create some data 
    DROP TABLE tmp.student CASCADE; 
    CREATE TABLE tmp.student 
        (sno INTEGER NOT NULL 
        , grade INTEGER 
        , sname varchar 
        ); 
    INSERT INTO tmp.student(sno) SELECT generate_series(1,10); 
    UPDATE tmp.student SET grade = sno*sno; 
    
    DROP TABLE tmp.entry CASCADE; 
    CREATE TABLE tmp.entry 
        (sno INTEGER NOT NULL 
        , sdate TIMESTAMP 
        ); 
    INSERT INTO tmp.entry(sno) SELECT generate_series(1,10); 
    
    -- table with interval lookup 
    DROP TABLE tmp.lookup CASCADE; 
    CREATE TABLE tmp.lookup 
        (llimit NUMERIC NOT NULL 
        , hlimit NUMERIC 
        , result varchar 
        ); 
    
    INSERT INTO lookup (llimit,hlimit,result) VALUES(70, NULL, 'Excellent'), (50, 70, 'Passed'), (30, 50, 'Failed') 
        ; 
    
    CREATE OR REPLACE FUNCTION stud_result(integer,numeric) RETURNS text 
    AS $BODY$ 
    DECLARE 
        stunum ALIAS FOR $1; 
        grade ALIAS FOR $2; 
        result TEXT; 
    BEGIN 
    
    SELECT COALESCE(lut.result, 'NOT TAKEN') INTO result 
        FROM student st, entry en 
        LEFT JOIN lookup lut ON (grade >= lut.llimit 
            AND (grade < lut.hlimit OR lut.hlimit IS NULL)) 
        WHERE st.sno = en.sno 
        AND st.sno = stunum 
        ; 
        RETURN result; 
    END; $BODY$ LANGUAGE PLPGSQL; 
    
    -- query joining students with their function values 
    SELECT st.* 
        , stud_result (st.sno, st.grade) 
        FROM student st 
        ; 
    

    그러나 잠깐 : 데이터 테이블에 속한

    sno | grade | sname | stud_result 
    -----+-------+-------+------------- 
        1 |  1 |  | NOT TAKEN 
        2 |  4 |  | NOT TAKEN 
        3 |  9 |  | NOT TAKEN 
        4 | 16 |  | NOT TAKEN 
        5 | 25 |  | NOT TAKEN 
        6 | 36 |  | Failed 
        7 | 49 |  | Failed 
        8 | 64 |  | Passed 
        9 | 81 |  | Excellent 
        10 | 100 |  | Excellent 
    (10 rows) 
    
    sno | sname | grade | result 
    -----+-------+-------+----------- 
        1 |  |  1 | NOT TAKEN 
        2 |  |  4 | NOT TAKEN 
        3 |  |  9 | NOT TAKEN 
        4 |  | 16 | NOT TAKEN 
        5 |  | 25 | NOT TAKEN 
        6 |  | 36 | Failed 
        7 |  | 49 | Failed 
        8 |  | 64 | Passed 
        9 |  | 81 | Excellent 
        10 |  | 100 | Excellent 
    (10 rows) 
    
    +0

    글쎄, 학생들은 스타일과 디자인을 배워야 만합니다. (하지만 어쩌면 일부 국가에서는 교사가 말한대로 할 것입니다.) – wildplasser

    +0

    알아두면 충분합니다. 다른 사람의 숙제를 망칠 수있는 방법. – wildplasser

    -1

    이 완전히 기능을 제거하기 및 사용 :

    -- Plain query 
    SELECT 
        st.sno, st.sname, st.grade 
        , COALESCE(lut.result, 'NOT TAKEN') AS result 
        FROM student st 
        LEFT JOIN lookup lut ON (1=1 
         AND lut.llimit <= st.grade 
         AND (lut.hlimit > st.grade OR lut.hlimit IS NULL) 
         ) 
        JOIN entry en ON st.sno = en.sno 
        ; 
    

    결과 : 당신은 단지뿐만 아니라 추악한 기능없이 할 수 있습니다 검색어 :

    SELECT 
        s.*, 
        CASE e.grade 
        WHEN >= 0 AND < 50 THEN 'failed' 
        WHEN >= 50 AND < 70 THEN 'passed' 
        WHEN >= 70 AND <= 100 THEN 'excellent' 
        ELSE 'not taken' 
        END 
    FROM 
    student s, 
    entry e 
    WHERE 
    s.sno = e.sno; 
    
    +0

    투표를 취소하면 이유를 추가하십시오. 이 기능을 사용하는 것은 그것을 수행하는 방법이 아닙니다. – tscho

    관련 문제