如何实现批量插入时逐条处理?解决PostgreSQL触发器多行返回报错
问题解决:批量插入时触发器报错的处理方案
错误原因分析
报错的核心是触发器函数deneme2()中的子查询select db_value from tbl_product_attribute_value where (db_attribute_id = 47 and db_attribute_value_id is null)在批量插入时返回了多行结果,而变量name只能接收单个值,导致赋值失败。同时原函数会一次性更新所有符合条件的行,不符合逐条处理的需求。
解决方案:修改触发器函数
调整函数逻辑,利用触发器的NEW对象获取当前插入行的信息,仅处理当前行,而非全表查询:
create or replace function deneme2() returns trigger as $$ declare idd integer; begin -- 生成新的tbl_attribute_value的db_id,兼容空表情况 idd := (SELECT COALESCE(MAX(db_id), 0) + 1 FROM public.tbl_attribute_value); -- 插入当前行对应的属性值到tbl_attribute_value insert into tbl_attribute_value (db_id, db_name) values (idd, NEW.db_value); -- 仅更新当前插入行的db_attribute_value_id(假设db_id是主键) update tbl_product_attribute_value SET db_attribute_value_id = idd WHERE db_id = NEW.db_id; return new; end; $$ language plpgsql;
关键修改点:
- 用
NEW.db_value直接获取当前插入行的属性值,避免全表查询返回多行的问题 - 更新操作通过
NEW.db_id定位到当前行,实现逐条独立处理 - 使用
COALESCE(MAX(db_id), 0)处理tbl_attribute_value为空表的情况,避免MAX(db_id)返回null导致计算错误
调整插入语句
无需添加LIMIT 1,直接执行批量插入即可,触发器会自动逐条处理每一行:
INSERT INTO tbl_product_attribute_value (db_id,db_product_id,db_category_id,db_attribute_id,db_attribute_value_id, db_value) VALUES (1999,217,2264,47,null , 'a'), (2000,217,2264,47,null , 'b') RETURNING * ;
原触发器保留
触发器本身是FOR EACH ROW类型,无需修改,继续使用:
create trigger assign_id_attribute_value after INSERT on tbl_product_attribute_value for each row execute procedure deneme2();
内容的提问来源于stack exchange,提问作者Eda Avcuoğlu
相关产品推荐
相关产品推荐

