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
bellpollbellpoll 

Trigger on Attachments

I have the requirement  create a trigger on Attachment object, when i add new attachment ,check the attchment alredy aded or not?

 

i write like this ,please suggest me, is it correct or not?

 

 

trigger dntAddDuplicateAttchmnt on Attachment (before insert) {
if(trigger.isBefore){
for(Attachment atch:Trigger.new){
String parentID=atch.ParentId;
String atchName=atch.Name;
List<Attachment> listatch=[SELECT Name,ParentId FROM Attachment];
if(parentID==trigger.oldmap.get(parentID).ParentId && atchName==trigger.oldmap.get(parentID).Name){
atch.addError(' This file already having with same name in your attachmntes');
}
else if{
for(Attachment at:listatch){
if(at.Name==atchName && at.ParentId==parentID){
atch.addError('This file already having with same name in your attachmntes');
}
}
}

}
}

}

Best Answer chosen by Admin (Salesforce Developers) 
Karthikeyan JayabalKarthikeyan Jayabal

Your code has a few mistakes:

  1. SOQL inside for loop
  2. Comparison is just based on file name, which is not effective. Instead you should compare based on the attachement's body & content type.

Below sample code will meet your requirement:

 

trigger AttachmentDupeCatcher on Attachment (before insert) {
    //Fetch parent Ids
    Set<Id> parentIds = new Set<Id>();
    for( Attachment a : trigger.new ) {
        parentIds.add(a.ParentId);
    }

    //Query already existing attachments on those parent records OUTSIDE A FOR LOOP
    List<Attachment> existingAttachments = [Select Id, ParentId, Name, Body, ContentType from Attachment where ParentId in :parentIds];
    
    //Compare incoming Attachments & existing Attachments based on the content
    for( Attachment incomingAttachment : trigger.new ) {
        for( Attachment existingAttachment : existingAttachments) {
            if( incomingAttachment.ParentId == existingAttachment.ParentId && incomingAttachment.Body.toString() == existingAttachment.Body.toString() && incomingAttachment.ContentType == existingAttachment.ContentType){
                incomingAttachment.addError(incomingAttachment.Name+' already exists.');
            }
        }
    }
}

 

All Answers

rohitrrohitr

You can remove the first if loop after querying records from your attachment object. The other if loop will do good.

JHayes SDJHayes SD

More details on the requirement?  An Attachment instance must be related to another record via the ParentId field.  Adding a trigger like you described will enforce the requirements on any attachment, regardless of what it's attached to.  Is there a specific object you're trying to target?

Karthikeyan JayabalKarthikeyan Jayabal

Your code has a few mistakes:

  1. SOQL inside for loop
  2. Comparison is just based on file name, which is not effective. Instead you should compare based on the attachement's body & content type.

Below sample code will meet your requirement:

 

trigger AttachmentDupeCatcher on Attachment (before insert) {
    //Fetch parent Ids
    Set<Id> parentIds = new Set<Id>();
    for( Attachment a : trigger.new ) {
        parentIds.add(a.ParentId);
    }

    //Query already existing attachments on those parent records OUTSIDE A FOR LOOP
    List<Attachment> existingAttachments = [Select Id, ParentId, Name, Body, ContentType from Attachment where ParentId in :parentIds];
    
    //Compare incoming Attachments & existing Attachments based on the content
    for( Attachment incomingAttachment : trigger.new ) {
        for( Attachment existingAttachment : existingAttachments) {
            if( incomingAttachment.ParentId == existingAttachment.ParentId && incomingAttachment.Body.toString() == existingAttachment.Body.toString() && incomingAttachment.ContentType == existingAttachment.ContentType){
                incomingAttachment.addError(incomingAttachment.Name+' already exists.');
            }
        }
    }
}

 

This was selected as the best answer
bellpollbellpoll

Thank you kartikeyan

bellpollbellpoll

ok and Thank you  Rohit

bellpollbellpoll
On Account object.... JHayes
bellpollbellpoll
yes accepted ,i think iterated for loop is effected on soql queries, but here i just use ( when) new only...that y i didn't think about that. is it r8?
JHayes SDJHayes SD

You may want to consider wrapping the code in an if block to only execute for Account instances:

 

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_id.htm

 

Otherwise the trigger logic will execute for attachments to any other object.