使用%TYPE在PostgreSQL中声明复合类型的变量

Dav*_*dEG 2 postgresql polymorphism types stored-procedures plpgsql

问题:如何在存储函数中声明相同类型的变量参数?

简单的答案是使用%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;
Run Code Online (Sandbox Code Playgroud)

但问题是何时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;
Run Code Online (Sandbox Code Playgroud)

这不起作用:

ERROR: type comp_type does not exist [SQL State=42704]
Run Code Online (Sandbox Code Playgroud)

那么当param1复合型时我该怎么办?

(注意:myVariable comp_type因为我的功能稍微复杂一点,所以不是一个好选择.)


编辑:我在复制和粘贴时出错,真正的错误是:

ERROR: invalid type name "param1%TYPE"
  Position: 130 [SQL State=42601] 
Run Code Online (Sandbox Code Playgroud)

并使用param1%ROWTYPE错误是:

ERROR: relation "param1" does not exist
  Where: compilation of PL/pgSQL function "test_function_2" near line 3 [SQL State=42P01] 
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 5

%ROWTYPE在那种情况下使用.

编辑 - 简单案例

AH和DavidEG的测试表明这不起作用.有趣的问题!
你可以尝试一种解决方法.只要您的定义与示例类似,您就可以简单地使用

CREATE FUNCTION test(param1 comp_type)
  RETURNS integer AS
$BODY$ 
DECLARE
    myvar comp_type;
BEGIN
    return 1;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE;
Run Code Online (Sandbox Code Playgroud)

但你真正的问题可能并不那么简单吗?

编辑2 - 真正的问题

正如所料,真正的问题更复杂:多态输入类型.该场景的
解决方法更难,但应该完美无缺:

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;
Run Code Online (Sandbox Code Playgroud)

呼叫:

SELECT a FROM test('("foo")'::comp_type); -- just retrieve a, ignore myvar
Run Code Online (Sandbox Code Playgroud)

查看完整输出:

SELECT * FROM test('("foo")'::comp_type);
Run Code Online (Sandbox Code Playgroud)

PostgreSQL 9.0+的注意事项

v9.0中有一个重要的更新.我引用发行说明:

  • 允许在PL/pgSQL函数中为输入参数赋值(Steve Prentice)

以前,输入参数被视为声明为CONST,因此函数的代码无法更改其值.已删除此限制以简化从未强加等效限制的其他DBMS移植函数的过程.输入参数现在的作用类似于初始化为传入值的局部变量.

因此,除了我的解决方法之外,您还可以直接使用输入变量.

动态归档名称