postgresql 返回表中的整行和其他表中的列

s4n0splo  于 2022-11-29  发布在  PostgreSQL
关注(0)|答案(1)|浏览(104)

我正在使用postgresql 14,并试图返回一个表中的整个记录以及不同表中的列。问题是,我不想在记录中写入所有标题。我尝试使用1(https://stackoverflow.com/questions/17821482/easy-way-to-have-return-type-be-setof-table-plus-additional-fields)中的指导线,但我得到了不同的错误。有人能告诉我我做错了什么吗?

CREATE OR REPLACE FUNCTION public.get_license_by_id(license_id_ integer)
    RETURNS TABLE(rec tbl_licenses, template_name character varying, company_name character varying)
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE SECURITY DEFINER PARALLEL UNSAFE
    ROWS 1000

AS $BODY$
DECLARE
BEGIN 
    CREATE TEMPORARY TABLE tempTable AS (
        SELECT 
            (rec).*, B.company_name, C.template_name 
            -- Tried using A instead of (rec).* with error: column "a" has pseudo-type record
        FROM 
        (
            (SELECT * FROM tbl_licenses) A
            LEFT JOIN
            (SELECT * FROM tbl_customers) B on A.customer_id = B.customer_id
            LEFT JOIN
            (SELECT * FROM tbl_templates) C on A.template_id = C.template_id
        )
    );
    UPDATE tempTable
    SET license = '1'
    WHERE tempTable.license IS NOT NULL;
    RETURN QUERY ( 
        SELECT * FROM tempTable
    );
    
    DROP TABLE tempTable;
    RETURN;
END;
$BODY$;

我像SELECT rec FROM get_license_by_id(1);一样调用函数,但得到:
错误:查询结构与函数结果类型DETAIL不匹配:返回整数类型与列1中预期tbl_licenses类型不匹配

jhiyze9q

jhiyze9q1#

您需要将A别名转换为正确的记录类型。但是,对于其他表,嵌套派生表不是必需的。如果在SELECT中为license列使用coalesce(),则还可以避免创建和更新临时表时的低效操作。

CREATE OR REPLACE FUNCTION get_license_by_id(license_id_ integer)
  RETURNS TABLE(rec tbl_licenses, template_name character varying, company_name character varying)
  LANGUAGE sql
  STABLE
AS $BODY$
  SELECT a::tbl_licenses, -- this is important
         B.company_name, C.template_name 
  FROM (
    select license_id, customer_id, ... other columns ..., 
           coalesce(license, '1') as license -- makes the temp table unnecessary
    from tbl_licenses A
  ) a
    LEFT JOIN tbl_customers B on A.customer_id = B.customer_id
    LEFT JOIN tbl_templates C on A.template_id = C.template_id
  where a.license_id = license_id_;
$BODY$
;

相关问题