2011-12-07 9 views
0

次のコードは私によく似ていますが、ポイントに作用します。この機能では、試験の成績に基づいて生徒の成績を表示する必要がありますが、最後の2つの陳述は実行されないため、生徒の得点が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 >= 70.0
  • grade >= 50.0 OR grade <= 70.0
  • grade > 0 OR grade < 50.0

(注)の枝にしたくない他の値の多くがそうであるようにゼロが第二の条件を満たしている:あなたはこれらを持っています条件付。私はあなたがこれらをしたいと思う:

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

gradeが指定されている場合にも、人はもちろんであるかどうかを確認するためにあなたのSELECT文を使用しているように見えるが、コースに参加していない場合は、NULL resultになります。 「コース内」チェックが機能の外にあるか、または返す前に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 
    ; 

しかし、待って:あなただけのようにも醜い機能せずに行うことができます。

-- 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 
    ; 

結果:

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

は完全に機能し、使用を取り除きますクエリ:

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

関連する問題