我们知道,有一种简单的方法可以将任何记录转换为PostgreSQL中相应的复合类型,如下所示:
CREATE TYPE test.t_test AS (
mytext text,
myint integer
);
SELECT ('text', 10)::test.t_test; -- will succeed
但是对此的一个不便是 - 如果目标类型被修改(例如添加了一个字段) - 那么演员将会破坏:(
ALTER TYPE test.t_test ADD ATTRIBUTE mychar char(1);
SELECT ('text', 10)::test.t_test; -- will fail
对于这种情况, 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
然后使用默认参数值。但这种方式既不清楚也不舒服。
答案 0 :(得分:4)
我的建议是,如果您需要这样做,请采取以下方法之一:
动态发现结构(使用pg_attribute
目录表)。这不能保证将来安全,但可能是。它也有一堆陷阱(例如,不要使用attnum
小于0的属性)。这通常是我采用的方法,并在Perl中编写库,以便在客户端进行此类发现。
创建使用类型和存储类型,并在它们之间进行转换。因此,您可以执行SELECT ('text', 10)::test.used_test::test.stored_test
,这将正常工作。但是有一个原因是你无法将记录转换为复合类型。