问题:如何在存储函数中声明相同类型的变量参数?
简单的答案是使用%TYPE
,这有效:
CREATE OR REPLACE FUNCTION test_function_1(param1 text)
RETURNS integer AS
$BODY$
DECLARE
myVariable param1%TYPE;
BEGIN
return 1;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
但问题是当param1
是复合类型时:
CREATE TYPE comp_type as
(
field1 text
)
CREATE OR REPLACE FUNCTION test_function_2(param1 comp_type)
RETURNS integer AS
$BODY$
DECLARE
myVariable param1%TYPE;
BEGIN
return 1;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
这不起作用:
ERROR: type comp_type does not exist [SQL State=42704]
那么当param1
是复合类型时我该怎么办?
(注意:只是myVariable comp_type
不是一个好选择,因为我的函数稍微更复杂。)
编辑: 我在复制和粘贴时遇到了错误,真正的错误是:
ERROR: invalid type name "param1%TYPE"
Position: 130 [SQL State=42601]
使用param1%ROWTYPE
错误是:
ERROR: relation "param1" does not exist
Where: compilation of PL/pgSQL function "test_function_2" near line 3 [SQL State=42P01]
答案 0 :(得分:5)
在这种情况下使用 %ROWTYPE
。
A.H.和DavidEG的测试显示这不起作用。有趣的问题!
您可以尝试解决方法。只要您的定义与示例类似,您就可以简单地使用
CREATE FUNCTION test(param1 comp_type)
RETURNS integer AS
$BODY$
DECLARE
myvar comp_type;
BEGIN
return 1;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
但你真正的问题可能不是那么简单吗?
正如所料,真正的问题更复杂:多态输入类型 该场景的解决方法更难,但应该完美无缺:
CREATE FUNCTION test(param1 anyelement, OUT a integer, OUT myvar anyelement)
RETURNS record AS
$BODY$
BEGIN
myvar := $1; -- myvar has now the required type.
--- do stuff with myvar.
myvar := NULL; -- reset if you don't want to output ..
a := 1;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
呼叫:
SELECT a FROM test('("foo")'::comp_type); -- just retrieve a, ignore myvar
查看完整输出:
SELECT * FROM test('("foo")'::comp_type);
v9.0中有一个重要的更新。我引用release notes:
- 允许在PL / pgSQL函数中为输入参数赋值 (Steve Prentice)
以前,输入参数被视为声明为CONST,因此 函数的代码无法更改其值。这个限制 已被删除,以简化从其他DBMS移植功能 不强加同等限制。现在输入参数 就像一个初始化为传入值的局部变量。
Ergo,除了我的解决方法之外,您还可以直接使用输入变量。