Postgres PL/pgSQL,可以声明匿名自定义类型吗?
Posted
技术标签:
【中文标题】Postgres PL/pgSQL,可以声明匿名自定义类型吗?【英文标题】:Postgres PL/pgSQL, possible to declare anonymous custom types? 【发布时间】:2016-01-19 08:17:48 【问题描述】:使用 DB2,我可以为我的用户定义函数声明匿名自定义类型(例如行类型或复合类型) - 请参阅以下示例(尤其是最后一行):
DB2 示例:
CREATE OR REPLACE FUNCTION myFunction(IN input1 DECIMAL(5), IN input2 DECIMAL(5))
RETURNS DECIMAL(2)
READS SQL DATA
LANGUAGE SQL
NO EXTERNAL ACTION
NOT DETERMINISTIC
BEGIN
DECLARE TYPE customAnonymousType AS ROW(a1 DECIMAL(2), a2 DECIMAL(2), a3 DECIMAL(2));
/* do something fancy... */
我可以用 PL/pgSQL 做类似的事情吗?我知道我可以使用现有的行类型,也可以使用现有的用户定义类型 - 但我真的必须提前定义类型吗?
我也知道 RECORD 类型,但据我了解,我无法在数组中使用它(而且它也不是一个定义明确的类型)。
评论要求一个例子,尽管它确实延长了很多我试图定义一个非常简单的例子(仍然适用于 DB2):
CREATE OR REPLACE FUNCTION myFunction(IN input1 DECIMAL(5), IN input2 DECIMAL(5))
RETURNS DECIMAL(2)
READS SQL DATA
LANGUAGE SQL
NO EXTERNAL ACTION
NOT DETERMINISTIC
BEGIN
DECLARE TYPE customAnonymousType AS ROW(a1 DECIMAL(2), a2 CHARACTER VARYING(50));
DECLARE TYPE customArray AS customAnonymousType ARRAY[INTEGER];
DECLARE myArray customArray;
SET myArray[input1] = (50, 'Product 1');
SET myArray[input2] = (99, 'Product 2');
RETURN myArray[ARRAY_FIRST(myArray)].a1;
END
这个函数当然只能作为一个虚拟函数(但我想这里的问题已经很长了)。实际上它只是根据 input1 是否大于 input2 来决定返回哪个数字。如果 input1 小于 input2,则返回 50,如果 input2 小于或等于 input2 则返回99.
我知道我什至没有使用我的类型的 a2 字符字段(所以在这种情况下,我也可以只使用数字数组)并且可能有很多很多根据输入值返回两个固定数字的更好解决方案,但如果我能够在 PL/pgSQL 中使用匿名自定义类型(就像我在 Oracle 或 DB2 过程中那样),或者是否有任何类似的替代方案,我的原始问题仍然存在.
【问题讨论】:
你能提供一个更详细的例子来说明你想用匿名类型做什么吗? PL/pgSQL 中很可能有一个解决方案,但它可能位于其他方向。 实际上我想将它们存储在一个数组中,因此 DB2 的下一行看起来像DECLARE TYPE myArray AS customAnonymousType ARRAY[INTEGER]
。该数组用于中间计算。
在没有该示例的情况下,您仍然应该发布:只需声明int[]
类型的变量。在 PG 中,数组是动态的,因此它们会随着您的数据需求而增长。 (虽然 PG 中的数组支持比其他 DBMS 好得多,但仍有很多不足之处。)但同样,也许您最好使用其他解决方案。
感谢第一个解决方案,不幸的是,只有当我的复合类型由数字组成的所有类型都是数字时,这才有可能。如果类型看起来像 DECLARE TYPE customAnonymousType AS ROW(a1 DECIMAL(2), a2 CHARACTER VARYING(50));
,那就不可能了。
而不是要求从 DB2 到 Postgresql 的翻译,而是解释真正的问题是什么。真正的问题不是实现,而是所需的输入和输出。
【参考方案1】:
您不能在 Postgres 中创建具有本地可见性的类型。不支持此功能。 Postgres 仅支持全局自定义复合类型。
请参阅CREATE TYPE 文档。此语句不能用于 plpgsql 块的DECLARE
部分。
【讨论】:
以上是关于Postgres PL/pgSQL,可以声明匿名自定义类型吗?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 Spring Data JPA Repository 的 @Query 注释中使用 PostgreSQL 匿名块(PL/pgSQL)?
在 Pl/pgSQL 中使用 FOR 循环时,它在 Postgres 11.8 中不起作用