我尝试使用非常简单的测试功能在plpgsql中返回多个值。测试函数采用整数作为输入,如果它是正数,负数和零,则应该返回。我已经看到了一些例子,但它们都是复杂的并且过了我的脑袋。
以下是我尝试的内容:
create or replace function test(v integer)
returns record as $$
BEGIN
IF v > 0
THEN return true as positive, false as negative, false as zero;
ELSEIF v < 0
THEN return false as positive, true as negative, false as zero;
ELSE
return false as positive, false as negative, true as zero;
END IF;
END;
$$ LANGUAGE plpgsql;
还试过这个
create or replace function test(v integer)
returns record as $$
DECLARE
result record;
BEGIN
IF v > 0
THEN
result.positive = true;
result.negative = false;
result.zero = false;
ELSEIF v < 0
THEN
result.positive = false;
result.negative = true;
result.zero = false;
ELSE
result.positive = false;
result.negative = false;
result.zero = true;
return result;
END IF;
END;
$$ LANGUAGE plpgsql;
也是这样:
IF v > 0
THEN
SELECT true, false, false into
result.positive, result.negative, result.zero;
ELSEIF v < 0
THEN
SELECT false, true, false into
result.positive, result.negative, result.zero;
ELSE
SELECT false, false, true into
result.positive, result.negative, result.zero;
return result;
END IF;
答案 0 :(得分:1)
我会按如下方式解决问题:
CREATE TYPE sign AS ENUM ('negative', 'zero', 'positive');
CREATE FUNCTION test(integer) RETURNS sign
LANGUAGE sql IMMUTABLE STRICT AS
$$SELECT CASE
WHEN $1 < 0
THEN 'negative'
WHEN $1 > 0
THEN 'positive'
ELSE 'zero'
END::sign$$;
如果您想像示例中那样返回record
,则必须使用ROW()
构造函数从三个布尔值中创建单个复合值:
RETURN ROW(true, false, false);
但是这个解决方案有它的缺点:你不能在SQL中访问复合类型的各个字段,因为PostgreSQL在分析时不知道字段:
test=> SELECT test(42);
┌─────────┐
│ test │
├─────────┤
│ (t,f,f) │
└─────────┘
(1 row)
test=> SELECT (test(42)).*;
ERROR: record type has not been registered
test=> SELECT * FROM test(42);
ERROR: a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM test(42);
^
您必须在查询中指定记录定义:
test=> SELECT positive FROM test(42) test(positive boolean, negative boolean, zero boolean);
┌──────────┐
│ positive │
├──────────┤
│ t │
└──────────┘
(1 row)
但是那种蔑视变量记录的目标。这就是为什么这些函数没有你引用的答案那么有用的原因。
答案 1 :(得分:1)
这将返回一条记录,因此结果将是(true,false,false)。
CREATE OR REPLACE FUNCTION test(v integer)
RETURNS record AS $$
DECLARE
result record;
BEGIN
SELECT true , false , false into result;
return result;
END;
问题是结果未命名,因此您拥有此( true, false, false)
,并且您希望单独获取每个值。为此,您可以这样做:
select a, b, c from test(1) AS (a BOOL, b bool, c bool);
答案 2 :(得分:1)
这是对我有用的“返回多个值”问题的解决方案。
坦白说,WAAAAAY花了很长时间才找到解决这种普遍需求的解决方案!像OP一样,我所见过的大多数示例都过于复杂,令人费解。当然,我什至在寻找示例的唯一原因是因为the docs对此初学者尚不明确。希望这对某人有帮助。
将下面的代码粘贴到pgAdmin查询窗口中,选择一种调用解决方案,然后执行。
create or replace function receive_two_values() returns void language plpgsql as
$main$
declare
returned record;
begin
create or replace function return_two_arguments(
arg1 text,
arg2 text,
out return1 text,
out return2 text)
language plpgsql as --"Returns record" is implied by multiple outs, so unnecessary here.
$$
begin
return1 := arg1;
return2 := arg2;
end;
$$;
returned = return_two_arguments('Hello', 'World');
raise notice 'return1="%"', returned.return1;
raise notice 'return2="%"', returned.return2;
end;
$main$;
--Invoke in one of at least two ways:
--ONE:
select receive_two_values();
--TWO:
do language plpgsql
$$
begin
perform receive_two_values();
end;
$$;
--Outputs:
--NOTICE: return1="Hello"
--NOTICE: return2="World"