Postgresql函数语法错误,接近语言plpgsql;

b1zrtrql  于 2023-05-17  发布在  PostgreSQL
关注(0)|答案(2)|浏览(190)

我遇到了一个plpgsql语法错误。
下面是错误消息:
错误:语法错误在“LANGUAGE”上或附近
第30行:语言plpgsql;
我解决了以前的一个语法错误,在我改变我的代码后,我得到了一个新的。
下面是我的代码:

drop function if exists get_person_and_subtable(integer);

CREATE OR REPLACE FUNCTION get_person_and_subtable(IN id integer)
RETURNS SETOF record 
AS $BODY$

DECLARE var_categ CHAR(5); 
DECLARE var_id INT = id;

BEGIN
    var_categ := (select PER_CATEG from T_PERSONNE where PER_ID = var_id);
    
    IF var_categ ='EMP' THEN RETURN QUERY 
        SELECT * FROM T_PERSONNE 
        INNER JOIN T_EMPLOYE ON T_PERSONNE.PER_ID = T_EMPLOYE.EMP_ID  
        WHERE PER_ID = var_id;
    END IF;
    IF var_categ ='PROSP' THEN RETURN QUERY 
        SELECT * FROM T_PERSONNE 
        INNER JOIN T_PROSPECT ON T_PERSONNE.PER_ID = T_PROSPECT.PROSP_ID  
        WHERE PER_ID = var_id;
    END IF;
    IF var_categ = 'VIS' THEN RETURN QUERY 
        SELECT * FROM T_PERSONNE
        INNER JOIN T_VISITEUR ON T_PERSONNE.PER_ID = T_VISITEUR.VIS_ID 
        WHERE PER_ID = var_id;
    END IF;
END;
$BODY$;
LANGUAGE plpgsql;
qvtsj1bj

qvtsj1bj1#

放错位置的分号是导致错误消息的直接原因。
但你的问题不会就此结束。您正试图将具有不同结果类型的三个不同查询硬塞进一个函数中。这几乎不可能您可以退回到RETURNS SETOF record,但这不是一个实用的解决方案。要调用这个函数,你必须在调用时提供一个列定义列表。因此,您必须事先知道将连接三个子表中的哪一个。如果你已经知道了这一点,那么使用一个具有“动态”输出的函数就没有意义了。第22条军规,这样下去毫无结果.
对单个函数使用单个返回类型。而且一开始就返回SETOF record很少有意义。而是返回一个定义良好的行类型。
更好的方法是运行这个普通查询:

SELECT *
FROM   t_personne p
LEFT   JOIN t_employe  e ON p.per_categ = 'EMP'   AND p.per_id = e.emp_id 
LEFT   JOIN t_prospect o ON p.per_categ = 'PROSP' AND p.per_id = o.prosp_id
LEFT   JOIN t_visiteur v ON p.per_categ = 'VIS'   AND p.per_id = v.vis_id
WHERE  p.per_id = _id;

就这样
所有三个子表的列都将包括在内,只有(至少)其中两个用空值填充。关键是要有一个稳定的返回类型。如果你坚持的话,你可以把它 Package 成一个函数。

hfwmuf9z

hfwmuf9z2#

删除$BODY$后的分号:

drop function if exists get_person_and_subtable(integer);

CREATE OR REPLACE FUNCTION get_person_and_subtable(IN id integer)
RETURNS SETOF record 
AS $BODY$

DECLARE var_categ CHAR(5); 
DECLARE var_id INT = id;

BEGIN
    var_categ := (select PER_CATEG from T_PERSONNE where PER_ID = var_id);
    
    IF var_categ ='EMP' THEN RETURN QUERY 
        SELECT * FROM T_PERSONNE 
        INNER JOIN T_EMPLOYE ON T_PERSONNE.PER_ID = T_EMPLOYE.EMP_ID  
        WHERE PER_ID = var_id;
    END IF;
    IF var_categ ='PROSP' THEN RETURN QUERY 
        SELECT * FROM T_PERSONNE 
        INNER JOIN T_PROSPECT ON T_PERSONNE.PER_ID = T_PROSPECT.PROSP_ID  
        WHERE PER_ID = var_id;
    END IF;
    IF var_categ = 'VIS' THEN RETURN QUERY 
        SELECT * FROM T_PERSONNE
        INNER JOIN T_VISITEUR ON T_PERSONNE.PER_ID = T_VISITEUR.VIS_ID 
        WHERE PER_ID = var_id;
    END IF;
END;
$BODY$
LANGUAGE plpgsql;

相关问题