2013-02-12 297 views
1

前幾天一切正常,除了配置文件外,沒有對系統進行任何新更改。Salesforce:System.LimitException:太多的SOQL查詢:101

突然我得到這個錯誤信息:

Error: Invalid Data. Review all error messages below to correct your data.
Apex trigger generateUniqueBidId caused an unexpected exception, contact your administrator: generateUniqueBidId: System.LimitException: Too many SOQL queries: 101

trigger generateUniqueBidId on Bids__c (before insert) { 

    Map<String, String> profilePrefixMap = new Map<String, String>(); 
    profilePrefixMap.put('Sales User', 'rds'); 
    profilePrefixMap.put('Super User', 'rds'); 
    profilePrefixMap.put('Standard User','SU'); 
    profilePrefixMap.put('System Administrator','SysAdmin'); 

    String defaultPrefix = ' '; 
    User user = [SELECT ProfileId FROM User Where Id = :Userinfo.getUserId() LIMIT 1]; 
    Profile profile = [SELECT Name FROM Profile Where Id = :user.ProfileId LIMIT 1]; 
    List<Bids__c> recentBids = [SELECT Id, CreatedById, Bid_unique_label__c From Bids__c WHERE Bid_unique_label__c = NULL]; 

    /**Logics for updating old Bids with correct Bid_id. May be refactored away when all bids are updated 
     Could cause problems if trigger system becomes to complicated. 
    */ 
    for (Bids__c bid : recentBids){ 
     String recentProfileName = [SELECT Profile.Name FROM User Where Id = :bid.CreatedById LIMIT 1].Profile.Name; 
     String bidId = profilePrefixMap.get(recentProfileName); 
     bid.Bid_unique_label__c = ((bidId == null) ? defaultPrefix : bidId);   
    } 
    upsert recentBids; 

    for (Bids__c bid : trigger.new){ 
     String bidId = profilePrefixMap.get(String.valueOf(profile.Name)); 
     bid.Bid_unique_label__c = ((bidId == null) ? defaultPrefix : bidId); 
    } 

} 

回答

3

你必須在一個循環中一個SOQL。

for (Bids__c bid : recentBids){ 
    String recentProfileName = [SELECT Profile.Name FROM User Where Id = :bid.CreatedById LIMIT 1].Profile.Name; 
    String bidId = profilePrefixMap.get(recentProfileName); 
    bid.Bid_unique_label__c = ((bidId == null) ? defaultPrefix : bidId);   
} 
upsert recentBids; 

這是一個性能殺手,其實我很驚訝的限制是100個查詢,曾經是一個觸發背景下不超過20個查詢。解決您的問題的一個快速方法是使用關係查詢和「點符號」。這將消除在循環中進行查詢的需要。

List<Bids__c> recentBids = [SELECT Id, CreatedBy.Profile.Name, Bid_unique_label__c 
FROM Bids__c 
WHERE Bid_unique_label__c = NULL]; 

for (Bids__c bid : recentBids){ 
    String recentProfileName = bid.CreatedBy.Profile.Name; 
    String bidId = profilePrefixMap.get(recentProfileName); 
    bid.Bid_unique_label__c = ((bidId == null) ? defaultPrefix : bidId);   
} 
upsert recentBids; 

此代碼仍然存在一些問題。

  1. 您可能會在單次交易中插入/更新不超過10K行的限制(您至少應該添加LIMIT子句)。
  2. 您正在將觸發器上下文中的數據與某些不相關內容上的數據修復混合在一起。您不應該「捎帶」,因爲用戶不會明白爲什麼他們會看到來自他們未觸及的數據的錯誤。
  3. 更何況「最後修改者」現在在你的系統中毫無價值。

如果是一次性清理壞數據的活動(修復唯一標籤) - 考慮運行數據修復並刪除此代碼。如果這確實是一個反覆出現的情況 - 寫一個批處理作業。

或者調查您是否可以編寫工作流規則來生成唯一鍵,看起來好像是可行的,並且配置會跳過編碼解決方案。

+0

這解決了現在的錯誤消息。 我現在將繼續使用代碼。 – user2063927 2013-02-19 12:13:21

+0

祝你好運,歡迎來到StackOverflow :) – eyescream 2013-02-19 12:30:20