因此,我需要更新一个大学数据库中名为register的表中的几列,该表的名称为exam_grade、lab_grade和final grade。最终成绩是根据exam_grade和lab_grade的结果计算的,但只要lab_grade的结果为NULL,则final_grade的结果不会直接变为exam_grade,而是仍为NULL。下面是函数的代码:
CREATE OR REPLACE FUNCTION public.fn_question_2_2(num integer)
RETURNS void
AS
$$
DECLARE
pointer record;
percentage numeric;
exam_i numeric;
lab_i numeric;
BEGIN
FOR pointer IN
(SELECT rg.amka, rg.lab_grade, rg.exam_grade,
rg.serial_number, rg.register_status,
cr.course_code, cr.lab_hours
FROM "Register" rg
JOIN (SELECT course_code, lab_hours FROM "Course") cr USING (course_code)
WHERE rg.register_status = 'approved' AND rg.serial_number = num)
LOOP
IF (pointer.exam_grade IS NULL) THEN
exam_i = floor((random()*(10-1)+1));
ELSE
exam_i = pointer.exam_grade;
END IF;
IF (pointer.lab_grade IS NULL AND pointer.lab_hours > 0) THEN
lab_i = floor((random()*(10-1)+1));
ELSE
lab_i = pointer.lab_grade;
END IF;
percentage = (SELECT exam_percentage FROM "CourseRun"
WHERE course_code = pointer.course_code AND serial_number = pointer.serial_number);
UPDATE "Register" r
SET lab_grade = lab_i ,exam_grade = exam_i,
final_grade = (SELECT
CASE WHEN pointer.lab_hours IS NOT NULL
THEN (floor(((lab_i*(100-percentage)) + exam_i * percentage)/100))
ELSE (exam_i)
END)
WHERE (final_grade IS NULL)
AND r.amka = pointer.amka
AND r.course_code = pointer.course_code
AND r.register_status = 'approved';
END LOOP;
END;
$$
LANGUAGE 'plpgsql';
-- DROP TABLE IF EXISTS public."CourseRun";
CREATE TABLE IF NOT EXISTS public."CourseRun"
(
course_code character(7) COLLATE pg_catalog."default" NOT NULL,
serial_number integer NOT NULL,
exam_min numeric,
lab_min numeric,
exam_percentage numeric,
labuses integer,
semesterrunsin integer NOT NULL,
CONSTRAINT "CourseRun_pkey" PRIMARY KEY (course_code, serial_number),
CONSTRAINT "CourseRun_course_code_fkey" FOREIGN KEY (course_code)
REFERENCES public."Course" (course_code) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT "CourseRun_labuses_fkey" FOREIGN KEY (labuses)
REFERENCES public."Lab" (lab_code) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT "CourseRun_semesterrunsin_fkey" FOREIGN KEY (semesterrunsin)
REFERENCES public."Semester" (semester_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public."CourseRun"
OWNER to postgres;```
```-- Table: public.Course
-- DROP TABLE IF EXISTS public."Course";
CREATE TABLE IF NOT EXISTS public."Course"
(
course_code character(7) COLLATE pg_catalog."default" NOT NULL,
course_title character(100) COLLATE pg_catalog."default" NOT NULL,
units smallint NOT NULL,
lecture_hours smallint NOT NULL,
tutorial_hours smallint NOT NULL,
lab_hours smallint NOT NULL,
typical_year smallint NOT NULL,
typical_season semester_season_type NOT NULL,
obligatory boolean NOT NULL,
course_description character varying COLLATE pg_catalog."default",
CONSTRAINT "Course_pkey" PRIMARY KEY (course_code)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public."Course"
OWNER to postgres;```
```-- Table: public.Register
-- DROP TABLE IF EXISTS public."Register";
CREATE TABLE IF NOT EXISTS public."Register"
(
amka character varying COLLATE pg_catalog."default" NOT NULL,
serial_number integer NOT NULL,
course_code character(7) COLLATE pg_catalog."default" NOT NULL,
exam_grade numeric,
final_grade numeric,
lab_grade numeric,
register_status register_status_type,
CONSTRAINT "Register_pkey" PRIMARY KEY (course_code, serial_number, amka),
CONSTRAINT "Register_course_run_fkey" FOREIGN KEY (serial_number, course_code)
REFERENCES public."CourseRun" (serial_number, course_code) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT "Register_student_fkey" FOREIGN KEY (amka)
REFERENCES public."Student" (amka) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
NOT VALID
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public."Register"
OWNER to postgres;```
amka|serial_number|course_code|exam_grade|final_grade|lab_grade|semes_status
"01010104188" 12 "ΑΓΓ 201" 6 6 10 "pass"
"01010104188" 12 "ΑΓΓ 202" 2 "approved"
"01010104188" 12 "ΗΡΥ 201" 8 9 10 "pass"
"01010104188" 12 "ΗΡΥ 202" 9 8 7 "pass"
"01010104188" 12 "ΗΡΥ 203" 7 8.40 9 "approved"
"01010104188" 12 "ΗΡΥ 204" 7 5.50 4 "approved"
"01010104188" 12 "ΗΡΥ 211" 9 "approved"
"01010104188" 12 "ΜΑΘ 107" 2 2 6 "fail"
"01010104188" 12 "ΠΛΗ 201" 7 0 2 "fail"
"01010104188" 12 "ΠΛΗ 202" 2 2.70 3 "approved"
"01010104188" 12 "ΠΛΗ 211" 8 7 5 "pass"
"01010104188" 12 "ΤΗΛ 201" 7 7 7 "pass"
"01010104188" 12 "ΤΗΛ 202" 4 3.20 2 "approved"
"01010104188" 12 "ΤΗΛ 211" 5 7.00 9 "approved"
任何帮助都将不胜感激,如果需要添加任何内容,以便您获得更好的视角,请这样说。
我尝试了许多不同的方法来编写查询,每次的结果都是一样的。当lab_grade为NULL时,我无法获取final_grade = exam_ grade。我没有收到任何错误消息,所以逻辑有问题。
2条答案
按热度按时间hs1ihplo1#
您可以使用
COALESCE
或签入您的CASE
:或
arknldoa2#
您的子查询是我们需要检查问题所在的地方,因为,由于您抱怨错误的值导致更新而不是缺少值更改。因此,让我们看看这个子查询:
NULL
是一个absorbing element,所以,无论你对它执行什么操作,结果都是NULL
。原因很简单:NULL
是缺少值,或者换句话说,它是未知。那么,结果是什么未知+ 2
比如说?当然,这是未知的。
因此,在不太了解您正在测试的数据的情况下,这些字段可能具有
NULL
值:lab_i
percentage
exam_i
因此,您可能需要确定默认值应该是什么,并使用这样的默认值作为
COALESCE
调用的参数,其形式为COALESCE(<your field or expression>, <the preferred default>)