问题描述
Postgresql中写C函数时,如果函数有out类型的参数,在C代码中 是 无法 为Out参数配置值的,因为return只能配置返回值无法配置out值,这是PG的框架问题,我们可以想办法规避。
例如下面的例子,如果在C语言中实现tp14函数,b、c的值都是无法配置的。
(这里是PL语言的例子,当然可以配置b、c的值,C函数办不到)
代码语言:javascript复制CREATE or replace function tp14(
a in integer ,
b out integer,
c out integer)
return int
LANGUAGE plpgsql
AS $$
BEGIN
b := 1;
c := 2;
return 100;
END;
$$;
select tp14(1,2,3);
解决方案
第一步:function改写成procedure,并把return值的类型加入到参数列表中,作为一个out类型的参数:
代码语言:javascript复制CREATE or replace procedure tp14_inner(
a in integer ,
b out integer,
c out integer,
rr out int) -- 添加 rr 参数,通过out作为返回值
LANGUAGE plpgsql
AS $$
BEGIN
b := 1;
c := 2;
rr := 100; -- return 100 改写为 rr := 100;
END;
$$;
这样在C语言中,可以return一个record类型(record需要和参数列表中的out数量、类型对齐),record类型中有三列:分别是整形1、整形2、整形100,return就可以一次性把所有需要的都返回了。
第二步:创建外层函数,保持与原函数接口一致。
外层函数负责保持与原函数接口一直,外层函数调用内层函数,将rr的值从out参数拿出来,重新return 回去即可!
代码语言:javascript复制CREATE or replace function tp14_outter(
a in integer ,
b out integer,
c out integer)
RETURNS int
LANGUAGE plpgsql
AS $$
DECLARE
rr int;
b int;
c int;
BEGIN
call tp14_inner(a, b, c, rr);
return rr;
END;
$$;
select tp14_outter(1, 0, 0);
tp14_outter
-------------
100