2013-02-12 3 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. Не говоря уже о том, что «последнее изменение» теперь бесполезно в вашей системе.

Если это одноразовая работа по очистке ваших плохих данных (исправить уникальные ярлыки) - подумайте над запуском исправления данных и удалением этого кода. Если это действительно повторяющаяся ситуация - напишите пакетное задание.

Или выясните, можете ли вы написать правило рабочего процесса для создания уникальных ключей, похоже, что это выполнимо, а config - кодирование решения.

+0

Это решение пока запустило сообщение об ошибке. Теперь я продолжу работу с кодом. – user2063927

+0

Удачи и приветствуем StackOverflow :) – eyescream

Смежные вопросы