PostgreSQL将记录转换为复合类型

beg*_*oth 13 sql postgresql casting

我们知道,有一种简单的方法可以将任何记录转换为PostgreSQL中相应的复合类型,如下所示:

CREATE TYPE test.t_test AS (
   mytext text,
   myint integer
);

SELECT ('text', 10)::test.t_test;  -- will succeed
Run Code Online (Sandbox Code Playgroud)

但是对此的一个不便是 - 如果目标类型被修改(例如添加了一个字段) - 那么演员将会破坏:(

ALTER TYPE test.t_test ADD ATTRIBUTE mychar char(1);

SELECT ('text', 10)::test.t_test;  -- will fail
Run Code Online (Sandbox Code Playgroud)

CREATE CAST对于这种情况可能会有所帮助,但我无法将伪类型RECORD作为参数传递给转换函数.并且类型继承和复合类型默认值(如表)都不起作用.有没有其他方法可以实现兼容性?

当然可以使用类似CREATE FUNCTION test.to_t_test(t text, i integer, c char DEFAULT '') RETURNS test.t_test然后执行的显式强制转换函数

SELECT test.to_t_test('text', 10)  -- OK
SELECT test.to_t_test('text', 10, '1')  -- OK
Run Code Online (Sandbox Code Playgroud)

然后使用默认参数值.但这种方式既不清楚也不舒服.

Chr*_*ers 4

我的建议是,如果您需要这样做,请采取以下方法之一:

  1. 动态发现结构(使用pg_attribute目录表)。这不能保证未来安全,但很可能是安全的。它也有很多陷阱(attnum例如,不要使用小于 0 的属性)。这通常是我采用的方法,并用 Perl 编写了库,用于在客户端进行此类发现。

  2. 创建使用类型和存储类型并在它们之间进行转换。因此你可以做一个SELECT ('text', 10)::test.used_test::test.stored_test并且效果很好。但是您无法将记录转换为复合类型是有原因的。