如何在PostgreSQL函数中访问自定义类型对象的属性值?
解决PostgreSQL自定义类型属性访问问题
你的问题核心是PostgreSQL对标识符的大小写处理规则:当定义自定义类型时,未加双引号的驼峰命名字段(如communityId)会被自动转换为全小写(communityid),但你在函数中用record.communityId访问时,PostgreSQL会将其解析为communityid,导致无法匹配到正确属性。
下面是两种可行的解决方法:
方法1:保留驼峰命名(需用双引号包裹标识符)
创建自定义类型时,给每个驼峰字段加上双引号,确保PostgreSQL保留原大小写;访问属性时同样用双引号包裹:
修改后的类型定义
CREATE TYPE BreakoutMatchingsDecrementProps AS ( "weekId" int, "communityId" varchar, "timeSlot" int, "groupSize" breakoutsize, "day" weekday );
修改后的函数
create or replace function Test (obj BreakoutMatchingsDecrementProps[]) returns void as $$ DECLARE record BreakoutMatchingsDecrementProps; BEGIN FOREACH record IN ARRAY obj LOOP update breakout_matching set number_of_registration = number_of_registration - 1 where week_id = 1 AND community_id = record."communityId" -- 用双引号包裹属性名 AND time_slot = 1 AND group_size = 'Two' AND day = 'Monday' AND number_of_registration > 0; END LOOP; -- 补充原代码遗漏的LOOP关键字 END $$ language plpgsql;
方法2:改用蛇形命名(更符合PostgreSQL惯例)
推荐使用PostgreSQL默认的蛇形命名法(snake_case),与数据库表字段命名风格保持一致,彻底避免大小写问题:
修改后的类型定义
CREATE TYPE BreakoutMatchingsDecrementProps AS ( week_id int, community_id varchar, time_slot int, group_size breakoutsize, day weekday );
修改后的函数
create or replace function Test (obj BreakoutMatchingsDecrementProps[]) returns void as $$ DECLARE record BreakoutMatchingsDecrementProps; BEGIN FOREACH record IN ARRAY obj LOOP update breakout_matching set number_of_registration = number_of_registration - 1 where week_id = 1 AND community_id = record.community_id -- 直接用蛇形命名访问 AND time_slot = 1 AND group_size = 'Two' AND day = 'Monday' AND number_of_registration > 0; END LOOP; -- 补充原代码遗漏的LOOP关键字 END $$ language plpgsql;
对应修改Supabase客户端代码
若使用方法2,客户端传参的键名也要同步改为蛇形:
const { data, error } = await adminClient.rpc( "test", { obj: { time_slot: 1, group_size: "Two", day: "Monday", community_id: "dshjdfdfak", week_id: 1, }, } );
内容的提问来源于stack exchange,提问作者jackbitthehe
相关产品推荐
相关产品推荐

