PostgreSQL 复合类型 INSERT INTO SELECT 需要强制转换

PostgreSQL Composite Types INSERT INTO SELECT Needs Casting

提问人:homam 提问时间:7/18/2022 更新时间:7/18/2022 访问量:363

问:

我想将查询中的一些记录插入到具有复合类型类型的列的表中。

create type ratio as (numerator bigint, denominator bigint);

create table my_ratios(id bigint, val ratio);

插入一些值自然有效:

insert into my_ratios (id, val) values (1, (22, 7)) returning *;  

但这并不:

-- this does not work:
insert into my_ratios 
SELECT 
   round(n::float / d * 100)
 , (n, d) as ratio -- cannot cast type record to ratio
FROM generate_series(21, 23) n
   , generate_series(6, 8) d
returning *;

我发现,如果我将行类型转换为文本并将文本转换回我的复合类型,则查询将起作用。但这是相当丑陋的:

insert into my_ratios 
SELECT 
  round(n::float / d * 100)
, cast(cast((n, d) as text) as ratio) -- note two casts
FROM generate_series(21, 23) n
   , generate_series(6, 8) d
returning *;

有没有我可以在这里使用的特殊语法?

SQL 小提琴

PostgreSQL 复合类型

评论


答:

1赞 user330315 7/18/2022 #1

您需要在 SELECT 列表中强制转换元组:

SELECT round(n::float / d * 100), 
       (n, d)::ratio 
FROM ...

或者,您可以使用cast( (n, d) as ratio)


请注意,只是为列分配一个别名。它对列的实际数据类型没有影响(a,b) as ratio