PostgreSQL 15.4中jsonb_to_recordset与jsonb_populate_recordset异常问题
问题原因与解决方法
你的问题确实是字段名大小写不匹配导致的,核心原因在于PostgreSQL对标识符的处理规则:
- 使用
->>操作符时,是直接按精确字符串匹配JSONB中的键名,大小写完全敏感,所以能正常获取驼峰式的productionNeedId、wantedDeliveryDate字段值。 - 但使用
jsonb_to_recordset或jsonb_populate_recordset时,PostgreSQL会把未用双引号包裹的标识符(列名、自定义类型字段名)自动转为小写。如果JSONB里的键是驼峰式,而你定义的列/类型字段是小写(或未用双引号保留大小写),就会出现字段匹配失败,要么取不到值,要么因为名字不匹配导致按位置赋值出现错位。
解决方法1:使用jsonb_to_recordset时保留字段大小写
在定义输出列时,必须用双引号包裹驼峰式的字段名,确保和JSONB中的键名完全一致:
SELECT "productionNeedId", quantity, "wantedDeliveryDate" FROM jsonb_to_recordset(pitems::jsonb) AS x( "productionNeedId" integer, quantity numeric, "wantedDeliveryDate" date );
双引号是关键,它告诉PostgreSQL不要将字段名转为小写,严格按指定的大小写匹配JSONB中的键。
解决方法2:使用jsonb_populate_recordset时修复自定义类型
创建自定义类型时,必须用双引号包裹驼峰式的字段名,保证类型字段名和JSONB键名大小写完全一致:
-- 先删除旧类型(如果已存在) DROP TYPE IF EXISTS rfditem_type; -- 创建保留大小写的自定义类型 CREATE TYPE rfditem_type AS ( "productionNeedId" integer, quantity numeric, "wantedDeliveryDate" date, "rfdId" integer -- 如果该字段存在,同样需要用双引号保留大小写 );
之后再调用jsonb_populate_recordset就能正确匹配字段:
SELECT * FROM jsonb_populate_recordset(null::rfditem_type, pitems::jsonb);
验证方法
在psql中执行\d+ rfditem_type,查看类型的字段名是否和JSONB中的键名大小写完全一致。如果字段名是小写(比如productionneedid),说明创建类型时没加双引号,需要重新创建。
内容的提问来源于stack exchange,提问作者Vitaly Ushakov
相关产品推荐
相关产品推荐

