Apex触发器获取StandardPricebookEntry ID并更新产品价格问题
问题修复与优化方案
核心错误修复
你遇到的Illegal assignment from Id to PricebookEntry错误,是因为错误地将Id类型值赋值给了PricebookEntry类型变量。同时代码还存在触发器事件范围不匹配、循环内SOQL、未定义变量引用等问题,以下是完整修复后的代码:
修改后的触发器代码
trigger UpdateProductPrice on Product2 (before insert, before update) { if (Trigger.isBefore) { // 收集需要更新价格的产品ID Set<Id> targetProductIds = new Set<Id>(); for (Product2 product : Trigger.new) { if (product.ProductPriceUpdate__c) { targetProductIds.add(product.Id); } } // 批量查询标准价格本条目,避免循环内SOQL触发 governor 限制 List<PricebookEntry> standardPricebookEntries = [ SELECT Id, UnitPrice, Product2Id FROM PricebookEntry WHERE Product2Id IN :targetProductIds AND Pricebook2.Name IN ('USA Pricebook', 'International PB') AND Product2.Name = 'Cabinet' AND Pricebook2.IsStandard = true ]; // 构建产品ID到价格条目的映射,方便快速匹配 Map<Id, PricebookEntry> productToPriceEntryMap = new Map<Id, PricebookEntry>(); for (PricebookEntry entry : standardPricebookEntries) { productToPriceEntryMap.put(entry.Product2Id, entry); } Decimal targetPrice = 1500; // 替换为你的目标标价 // 批量处理价格更新 for (Product2 product : Trigger.new) { if (product.ProductPriceUpdate__c && productToPriceEntryMap.containsKey(product.Id)) { PricebookEntry targetEntry = productToPriceEntryMap.get(product.Id); UpdatePriceBook.UpdatePrice(targetEntry.Id, targetPrice); } } } }
修改后的工具类代码
public class UpdatePriceBook { // 简化方法参数,移除未使用的productId public static void UpdatePrice(Id pricebookEntryId, Decimal newPrice){ try { PricebookEntry pricebookEntry = [SELECT Id, UnitPrice FROM PricebookEntry WHERE Id = :pricebookEntryId]; pricebookEntry.UnitPrice = newPrice; update pricebookEntry; System.debug('Price updated successfully for entry ID: ' + pricebookEntryId); } catch (Exception e) { System.debug('Error updating price: ' + e.getMessage()); } } // 可选:批量更新方法,减少DML操作次数,提升性能 public static void BulkUpdatePrice(Map<Id, Decimal> entryIdToPriceMap){ if(entryIdToPriceMap == null || entryIdToPriceMap.isEmpty()) return; List<PricebookEntry> entriesToUpdate = [SELECT Id, UnitPrice FROM PricebookEntry WHERE Id IN :entryIdToPriceMap.keySet()]; for(PricebookEntry entry : entriesToUpdate){ entry.UnitPrice = entryIdToPriceMap.get(entry.Id); } try{ update entriesToUpdate; System.debug('Bulk updated ' + entriesToUpdate.size() + ' pricebook entries'); } catch(Exception e){ System.debug('Error bulk updating prices: ' + e.getMessage()); } } }
关键修改说明
修复类型赋值错误
原代码中PricebookEntry standardPricebookEntry = standardPricebookEntries[0].id;是类型不匹配,正确写法是先获取对象再取ID:PricebookEntry standardPricebookEntry = standardPricebookEntries[0]; Id entryId = standardPricebookEntry.Id;修正触发器事件范围
原触发器仅定义为before insert,但代码中判断了Trigger.isInsert || Trigger.isUpdate,导致产品更新时触发器不执行。修改为before insert, before update,覆盖插入和更新场景。移除循环内SOQL
循环内执行SOQL会触发Salesforce的查询次数限制,改为先收集所有目标产品ID,再批量查询价格条目,通过映射快速匹配产品与价格条目。简化工具类参数
原方法中的productId仅用于日志打印,无实际业务作用,直接移除以减少不必要的查询。
内容的提问来源于stack exchange,提问作者iluvcode
相关产品推荐
相关产品推荐

