提问人:L. Rodgers 提问时间:10/21/2022 更新时间:10/21/2022 访问量:451
Postgresql:如何解决伪类型记录错误
Postgresql: How to work around pseudo-type record errors
问:
伪记录错误一直是一个相当普遍的问题,问题在于让 Postgres 相信它有一个工作行集。有时,使用看起来像伪记录但用作完全具体化记录集的中间记录类型可能更容易,而无需创建和转换为正式的“类型”[记录类型]。
/*
-- This wont work, causes pseudo-type record error
*/
CREATE TEMP TABLE tmpErrPseudoSave AS
SELECT ROW( col2, col1 ) AS anonrow FROM tmpOrigDat ;
答:
0赞
L. Rodgers
10/21/2022
#1
从 PostgreSql 版本 13 开始,有一个不错的解决方法。这是通过将返回集封装为内部查询 CTE 来实现的,外部查询可以看到并将其用作完全具体化的状态。
/**
we can save it however if we just create the anon row
but re-expand it right away saving the fields as generic f1, f2 ....
( renames every field automatically )
*/
CREATE TEMP TABLE tmpPseudoSave AS
SELECT (rowrow).* -- expand the anon table struct as f1, f2 ....
FROM /** s1 is fully materialized **/
( SELECT ROW( (zz).* ) rowrow FROM (SELECT * FROM tmpOrigDat ) zz ) s1
;
甚至可以即时将行类型转换为新的兼容类型:
DROP TABLE IF EXISTS tmpNewRowType;
CREATE TEMP TABLE tmpNewRowType AS
SELECT NULL::CHAR(1) AS zCol1newname2
,NULL::INT AS zCol2newname1
LIMIT 0; /** empty object **/
SELECT * FROM tmpNewRowType ;
SELECT ((r)::tmpNewRowType).*
FROM ( SELECT * FROM tmpPseudoSave ) r /** needs to be encapsulated as a CTE subselect (r)**/
;
这种列别名可以从数据字典中由表驱动,使用匿名 DO LOOP 在其正确的匹配序号位置构建匹配的列别名。
在 PostgreSql 13 之前,无法保存中间伪类型行类型,您必须转换为预定义的行类型(存储为正式的 Postgres 类型、表或临时表)。
CREATE TEMP TABLE tmpFinalSave AS
SELECT ( s1::tmpNewRowType ).*
FROM ( SELECT * FROM tmpOrigDat ) s1 ;
zcol1newname2 zcol2newname1
a 1
b 2
c 3
d 4
e 5
dbfiddle.uk 的完整演示
下一个:我们可以在方法中声明接口吗?
评论