function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Jeff BomarJeff Bomar 

create a query and place the results in a custom field

Trying to create an Apex trigger to query the price-book entries and place the result in a custom field can someone please tell me what i am doing wrong 
get two problems Expression must be a list type: pricebookEntry 
and a value cannot be stored to Hourly_Cost__c in type Custom_Programming__C


trigger updateCustomDev on Custom_Programming__c (after update) {
  

    //SQL statement to lookup price 
    PricebookEntry sqlResult = [SELECT UnitPrice 
        FROM PricebookEntry 
        WHERE Product2.Name = 'Custom Development'
                               AND PriceBook2.Name='DAKCS'];

    //save the returned SQL result inside the field 
    Custom_Programming__c.Hourly_Cost__c = sqlResult[0].UnitPrice;
      
}
Best Answer chosen by Jeff Bomar
Daniel AhlDaniel Ahl

Hello Jeff!

First off, sqlResult has to be a List<PricebookEntry> since you aren't limiting how many records can be fetched:
 

List<PricebookEntry> sqlResult = [SELECT UnitPrice 
        FROM PricebookEntry 
        WHERE Product2.Name = 'Custom Development'
                               AND PriceBook2.Name='DAKCS'];

OR

PricebookEntry sqlResult = [SELECT UnitPrice FROM PricebookEntry WHERE Product2.Name = 'Custom Development' AND PriceBook2.Name = 'DAKCS' LIMIT 1];

Since your trigger is on after update, at the end you would have to use an "update", or change it to "(before update)".
If you change it to before update you don't have to trigger the same trigger again, but if there is a reason for it to be an after update trigger, then leave it as is, and just update the record at the end.

Your trigger as an "before update"-trigger:
trigger updateCustomDev on Custom_Programming__c (before update) {
    //SQL statement to lookup price 
    PricebookEntry sqlResult = [SELECT UnitPrice 
        FROM PricebookEntry 
        WHERE Product2.Name = 'Custom Development'
        AND PriceBook2.Name = 'DAKCS' LIMIT 1];
    
    
    for(Custom_Programming__c CP : Trigger.new){
        //Set the returned SQL result inside the field 
        CP.Hourly_Cost__c = sqlResult.UnitPrice;
    }
    
}

Your trigger as an "after update"-trigger:
trigger updateCustomDev on Custom_Programming__c (after update) {
    //SQL statement to lookup price 
    PricebookEntry sqlResult = [SELECT UnitPrice 
        FROM PricebookEntry 
        WHERE Product2.Name = 'Custom Development'
        AND PriceBook2.Name = 'DAKCS' LIMIT 1]; // LIMIT 1 limits the amount of records that is being returned to 1.
    
    //Creating a list of records from the Trigger.new that we can use later for update:
    List<Custom_Programming__c> CPs = new List<Custom_Programming__c>(Trigger.new);
    
    for(Custom_Programming__c CP : CPs){ //Looping through each Custom_Programming__c record that enters the trigger.
        //Set the returned SQL result inside the field 
        CP.Hourly_Cost__c = sqlResult.UnitPrice;
    }
    update CPs;
}

All Answers

Daniel AhlDaniel Ahl

Hello Jeff!

First off, sqlResult has to be a List<PricebookEntry> since you aren't limiting how many records can be fetched:
 

List<PricebookEntry> sqlResult = [SELECT UnitPrice 
        FROM PricebookEntry 
        WHERE Product2.Name = 'Custom Development'
                               AND PriceBook2.Name='DAKCS'];

OR

PricebookEntry sqlResult = [SELECT UnitPrice FROM PricebookEntry WHERE Product2.Name = 'Custom Development' AND PriceBook2.Name = 'DAKCS' LIMIT 1];

Since your trigger is on after update, at the end you would have to use an "update", or change it to "(before update)".
If you change it to before update you don't have to trigger the same trigger again, but if there is a reason for it to be an after update trigger, then leave it as is, and just update the record at the end.

Your trigger as an "before update"-trigger:
trigger updateCustomDev on Custom_Programming__c (before update) {
    //SQL statement to lookup price 
    PricebookEntry sqlResult = [SELECT UnitPrice 
        FROM PricebookEntry 
        WHERE Product2.Name = 'Custom Development'
        AND PriceBook2.Name = 'DAKCS' LIMIT 1];
    
    
    for(Custom_Programming__c CP : Trigger.new){
        //Set the returned SQL result inside the field 
        CP.Hourly_Cost__c = sqlResult.UnitPrice;
    }
    
}

Your trigger as an "after update"-trigger:
trigger updateCustomDev on Custom_Programming__c (after update) {
    //SQL statement to lookup price 
    PricebookEntry sqlResult = [SELECT UnitPrice 
        FROM PricebookEntry 
        WHERE Product2.Name = 'Custom Development'
        AND PriceBook2.Name = 'DAKCS' LIMIT 1]; // LIMIT 1 limits the amount of records that is being returned to 1.
    
    //Creating a list of records from the Trigger.new that we can use later for update:
    List<Custom_Programming__c> CPs = new List<Custom_Programming__c>(Trigger.new);
    
    for(Custom_Programming__c CP : CPs){ //Looping through each Custom_Programming__c record that enters the trigger.
        //Set the returned SQL result inside the field 
        CP.Hourly_Cost__c = sqlResult.UnitPrice;
    }
    update CPs;
}
This was selected as the best answer
Jeff BomarJeff Bomar
Thanks So much, I was able to get it to work now I just need to figure out how to write a test class so I can get it in my production org.