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

时间:2011-10-03 12:03:36

标签: postgresql stored-procedures types polymorphism 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;

但问题是当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] 

1 个答案:

答案 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;

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

编辑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;

呼叫:

SELECT a FROM test('("foo")'::comp_type); -- just retrieve a, ignore myvar

查看完整输出:

SELECT * FROM test('("foo")'::comp_type);

PostgreSQL 9.0 +

的注释

v9.0中有一个重要的更新。我引用release notes

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

以前,输入参数被视为声明为CONST,因此   函数的代码无法更改其值。这个限制   已被删除,以简化从其他DBMS移植功能   不强加同等限制。现在输入参数   就像一个初始化为传入值的局部变量。

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

动态归档名称