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
Ralf WittenbergerRalf Wittenberger 

Error on Trigger Lookup

i have a new problem, I receive the error message

List has more than 1 row for assignment to SObject Trigger.MoveAtt: line 9, column 1

for the following trigger.

trigger MoveAtt on Attachment (after insert) {
    List<Id> forDeletionIds = new List<Id>();
    for (Attachment a : trigger.new){
    String parentIdString = String.valueof(a.parentId);
    if (parentIdString.substring(0,3) == '00T'){
        System.debug(a.parentId);
        if(Task.WhatId != null){
            if(Customer_Document__c.Task_ID__c != null){
            Customer_Document__c parent1 = [SELECT Id  FROM Customer_Document__c WHERE Task_ID__c = :a.parentId and CreatedDate__c = :a.CreatedDate ];
        if (parent1.Id  != null){
            Attachment body = [SELECT Body FROM Attachment WHERE Id = :a.Id];
            Attachment newA = New Attachment(
                Name = a.Name,
                Body = body.Body,
                Description = 'Email Attachment from ' + date.today(),
                OwnerId = a.OwnerId,
                ParentId = parent1.Id
            );
        }} 
        task parent = [SELECT Id,WhoId  FROM Task WHERE Id = :a.parentId];
        if (parent.WhoId  != null){
            Attachment body = [SELECT Body FROM Attachment WHERE Id = :a.Id];
            Attachment newA = New Attachment(
                Name = a.Name,
                Body = body.Body,
                Description = 'Email Attachment from ' + date.today(),
                OwnerId = a.OwnerId,
                ParentId = parent.WhoId
            );
            insert newA;
            forDeletionIds.add(a.Id);
        }
      }
    }
List<Attachment> forDeletion = [SELECT Id FROM Attachment WHERE Id IN :forDeletionIds];
delete forDeletion;
    }}
Ashish_Sharma_DEVSFDCAshish_Sharma_DEVSFDC
Hi ,

Please use below code ,it uses Limit in query.
trigger MoveAtt on Attachment (after insert) {
    List<Id> forDeletionIds = new List<Id>();
    for (Attachment a : trigger.new){
    String parentIdString = String.valueof(a.parentId);
    if (parentIdString.substring(0,3) == '00T'){
        System.debug(a.parentId);
        if(Task.WhatId != null){
            if(Customer_Document__c.Task_ID__c != null){
            Customer_Document__c parent1 = [SELECT Id  FROM Customer_Document__c WHERE Task_ID__c = :a.parentId and CreatedDate__c = :a.CreatedDate Limit 1];
        if (parent1.Id  != null){
            Attachment body = [SELECT Body FROM Attachment WHERE Id = :a.Id];
            Attachment newA = New Attachment(
                Name = a.Name,
                Body = body.Body,
                Description = 'Email Attachment from ' + date.today(),
                OwnerId = a.OwnerId,
                ParentId = parent1.Id
            );
        }} 
        task parent = [SELECT Id,WhoId  FROM Task WHERE Id = :a.parentId];
        if (parent.WhoId  != null){
            Attachment body = [SELECT Body FROM Attachment WHERE Id = :a.Id];
            Attachment newA = New Attachment(
                Name = a.Name,
                Body = body.Body,
                Description = 'Email Attachment from ' + date.today(),
                OwnerId = a.OwnerId,
                ParentId = parent.WhoId
            );
            insert newA;
            forDeletionIds.add(a.Id);
        }
      }
    }
List<Attachment> forDeletion = [SELECT Id FROM Attachment WHERE Id IN :forDeletionIds];
delete forDeletion;
    }}

Let us know if it helps.
Ralf WittenbergerRalf Wittenberger
Hi Ashish,

thanks for your early reply, unfortunately, when i use the limit 1, it saves the attachment to a object, starting with a09 and I can´t find it anymore. Do you have any further idea?
Ashish_Sharma_DEVSFDCAshish_Sharma_DEVSFDC
Hi Ralf,

Try below code,
I have removed queries from loop and have used Map instead.
 
trigger MoveAtt on Attachment (after insert) {
    List<Id> forDeletionIds = new List<Id>();
	
	Set<Id> toQueryParentIds = new Set<Id>();
	Set<Date> dateSetToQuery = new Set<Date>();
	for(Attachment a : trigger.new){
			toQueryParentIds.add(a.parentId);
			dateSetToQuery.add.CreatedDate);		
	}
	Map<Id,Customer_Document__c> mapParent1 = new Map<Id,Customer_Document__c>([SELECT Id  FROM Customer_Document__c WHERE Task_ID__c in:toQueryParentIds and CreatedDate__c in:dateSetToQuery]);
    Map<Id,Task> taskparentMap = new  Map<Id,Task>([SELECT Id,WhoId  FROM Task WHERE Id = :toQueryParentIds]);
	
	for (Attachment a : trigger.new){
    String parentIdString = String.valueof(a.parentId);
    if (parentIdString.substring(0,3) == '00T'){
        System.debug(a.parentId);
        if(Task.WhatId != null){
            if(Customer_Document__c.Task_ID__c != null){
            //Customer_Document__c parent1 = [SELECT Id  FROM Customer_Document__c WHERE Task_ID__c = :toQueryParentIds and CreatedDate__c = :a.CreatedDate Limit 1];
        if (mapParent1.get(a.parentId).Id  != null){
            Attachment body = [SELECT Body FROM Attachment WHERE Id = :a.Id];
            Attachment newA = New Attachment(
                Name = a.Name,
                Body = body.Body,
                Description = 'Email Attachment from ' + date.today(),
                OwnerId = a.OwnerId,
                ParentId = mapParent1.get(a.parentId).Id
            );
        }} 
        
        if (taskparentMap.get(a.parentId).WhoId  != null){
            Attachment body = [SELECT Body FROM Attachment WHERE Id = :a.Id];
            Attachment newA = New Attachment(
                Name = a.Name,
                Body = body.Body,
                Description = 'Email Attachment from ' + date.today(),
                OwnerId = a.OwnerId,
                ParentId = taskparentMap.get(a.parentId).WhoId
            );
            insert newA;
            forDeletionIds.add(a.Id);
        }
      }
    }
List<Attachment> forDeletion = [SELECT Id FROM Attachment WHERE Id IN :forDeletionIds];
delete forDeletion;
    }}

Let us know if it helps.
Ralf WittenbergerRalf Wittenberger
Will check that.

Can you please explain how to check queries in the console?
Ashish_Sharma_DEVSFDCAshish_Sharma_DEVSFDC
Please go through https://help.salesforce.com/apex/HTViewHelpDoc?id=code_dev_console_tab_query_editor.htm&language=en_US (https://help.salesforce.com/apex/HTViewHelpDoc?id=code_dev_console_tab_query_editor.htm&language=en_US) link.
Ralf WittenbergerRalf Wittenberger
checked that alreaday with  SELECT Id  FROM Customer_Document__c where IssueDate__c != null
works, but when i try SELECT Id  FROM Customer_Document__c where IssueDate__c = date.today()
it returns " Unknown error parsing query"
 
Ralf WittenbergerRalf Wittenberger
and when i try  SELECT Id  FROM Customer_Document__c WHERE Task_ID__c = :a.ParentId   it returns same error message but i would to check, why it returns more then 1 row...is there another possibility to check the results to find the failure?
Ashish_Sharma_DEVSFDCAshish_Sharma_DEVSFDC
Check Debug logs then.

Regards
ashish.sharma.devsfdc@gmail.com
Ralf WittenbergerRalf Wittenberger
I checked, it always returns 2 rows...but how can i see, what kind of 2 objects the query is returning? Can i build a list with that trigger to check results? maybe the second object is only a dummy object, not yet saved.
Ashish_Sharma_DEVSFDCAshish_Sharma_DEVSFDC
Hi Rafl,

Your query is on "Customer_Document__c" object ,so it should return Customer_Document__c records.
 
Ralf WittenbergerRalf Wittenberger
Hi again,

the following trigger works well in sandbox, is validated in production, but when i used email to salesforce, it returns the following:

UnexpectedException: MoveAtt: execution of AfterInsert  caused by: System.QueryException: Non-selective query against large object type (more than 100000 rows). Consider an indexed filter or contact salesforce.com about custom indexing. Even if a field is indexed a filter might still not be selective when: 1. The filter value includes null (for instance binding with a list that contains null) 2. Data skew exists whereby the number of matching rows is very large (for instance, filtering for a particular foreign key value that occurs many times)  Trigger.MoveAtt: line 9, column 1


Trigger is as follows

trigger MoveAtt on Attachment (after insert) {
    List<Id> forDeletionIds = new List<Id>();
    for (Attachment a : trigger.new){
    String parentIdString = String.valueof(a.parentId);
    if (parentIdString.substring(0,3) == '00T'){
        System.debug(a.parentId);
        if(Task.WhoId != null){
            if(Customer_Document__c.Task_ID__c != null){  
        Customer_Document__c parent = [SELECT Id  FROM Customer_Document__c WHERE Task_ID__c = :a.ParentId Limit 1 ];
        if (parent.Id  != null){
            Attachment body = [SELECT Body FROM Attachment WHERE Id = :a.Id];
            Attachment newA = New Attachment(
                Name = a.Name,
                Body = body.Body,
                Description = 'Email Attachment from ' + date.today(),
                OwnerId = a.OwnerId,
                ParentId = parent.Id
            );
            insert newA;
            forDeletionIds.add(a.Id);
        }  } }  }
List<Attachment> forDeletion = [SELECT Id FROM Attachment WHERE Id IN :forDeletionIds];
delete forDeletion;
    }}

How can i prevent looking for nulls? I don´t know, which Objects causes the 100000 rows.