关于MySQL函数返回表的问题

之前做作业的时候,有一个题目要求用mysql的函数完成一个查询,我写了一下,死活过不了编译,显示有syntax error。我从网上抄了好几个语法,都不对,最后一版是这样的。

DELIMITER //
CREATE FUNCTION get_student_courses(sno_param CHAR(9))
RETURNS TABLE (
    Sname VARCHAR(255),
    Cno INT,
    Grade INT
)
DETERMINISTIC
READS SQL DATA
BEGIN
    RETURN (
        SELECT S_T_U2022xxxxx.Student.Sname, S_T_U2022xxxxx.SC.Cno, S_T_U2022xxxxx.SC.Grade
        FROM S_T_U2022xxxxx.Student
        JOIN S_T_U2022xxxxx.SC ON S_T_U2022xxxxx.Student.Sno = sno_param
    );
END;
//
DELIMITER ;

我非常疑惑,明明和网上资料是一样的,为什么不行?我只好硬着头皮去看mysql文档。

这里,我们可以看到:

Parameter types and function return types can be declared to use any valid data type

那么有哪些valid data type呢?在这里可以发现,valid data type包括:

MySQL supports SQL data types in several categories: numeric types, date and time types, string (character and byte) types, spatial types, and the JSON data type.

stored function的返回值类型必须是这些类型中的一种。那么我们可以看到,TABLE并不在这些类型中,因此我们无法使用TABLE作为返回值类型。

还有一种函数类型是loadable function的返回值类型更简单了,只能是{STRING|INTEGER|REAL|DECIMAL}.

我认为,我们可以得出结论,就是mysql不支持函数返回这种操作。为什么呢?我认为,数据库中主要还是把视作一个数据结构,而不是一个数据类型,过于复杂的数据结构不适合作为返回值类型。

那么,如何实现这一功能呢?可以在函数内部完成查询,把结果用字符串的形式返回,例如:

DELIMITER //

CREATE FUNCTION get_student_courses(sno_param CHAR(9))
RETURNS VARCHAR(2048)
DETERMINISTIC
READS SQL DATA
BEGIN
    DECLARE result VARCHAR(2048);

    SELECT GROUP_CONCAT(CONCAT(S.Sno, ' ', S.Sname, ' ', C.Cno, ' ', C.Cname, ' ', SC.Grade) SEPARATOR '; ')
    INTO result
    FROM Student S
    JOIN SC ON S.Sno = SC.Sno
    JOIN Course C ON SC.Cno = C.Cno
    WHERE S.Sno = sno_param;

    RETURN result;
END //

DELIMITER ;

当然,最好的办法就是只在数据库中完成增删查改,对于复杂的操作可以在外部程序中完成,少整些花里胡哨的。

毕竟,不是人人都是mysql仙人。

results matching ""

    No results matching ""