+ Start a Discussion
EUSEUS 

Before Insert Trigger question

Hi,

 

I wrote a Trigger to prevent the insertion of a new record whithin an SetUp__c  sObject if already exists ANY active records in there (the idea is that only one record should exist in that sObject). However the new record is inserted no matter what.

Here is the trigger code:

 

 

trigger NewSetUpRecord on SetUp__c (before insert) {

      List<SetUp__c> SUR = [SELECT Id, Name, IsDeleted FROM SetUp__c WHERE IsDeleted = false AND  id  IN :Trigger.new];

      boolean exists = false;

      if (SUR.size()>0) {

                      for (SetUp__c sr : SUR) {

                                 if (sr.IsDeleted) {}

                                 else {

                                   exists = true;

                                   break;

                                 }

                      }

                      if (!exists) {

                         insert SUR;

                      }

     }

}

 

Any ideas why this might be happening?

 

Thanks!

Best Answer chosen by Admin (Salesforce Developers) 
MellowRenMellowRen

EUS

 

Note: You have posted this on the wrong board, you should put it in the Apex Code area for better responses. Not sure if you can swap it now.

 

If you simply want to prevent any SetUp object from being created unless none currently exists then this should do it (sorry I can't test but it should be close):

 

trigger NewSetUpRecord on SetUp__c (before insert) {
    Integer suCount = [SELECT count() FROM SetUp__c LIMIT 1];
    if (suCount > 0) {
        for (SetUp__c aSUObject : trigger.new) {
            aSUObject.Name.addError('An active object already exists'); //assuming there is a field called 'Name'.
        }
    }
}

 

This should even work for a mass data load—but you should test. Does it do what you need? Or am I misreading your question?

 

A few comments to help you see what you did:

 

  1. A before trigger allows you to modify/validate data before Salesforce commits the record to the database. Your trigger never actually stops the record from being saved (that is what the addError method does). In fact, had your code ever decided that it was OK to save it would have executed the INSERT command, which would have re-fired this trigger (before the save) which would have become infinitely recursive and eventually generate a Salesforce error.
     
  2. That being said you would not get this infinite loop because your SOQL query would not be returning any results. You are trying to find all existing records whose unique ID is the same as the ID of the records you are about to insert.  :-)
     
  3. Plus, and I could be wrong here, assuming unique IDs weren't unique, I don't think that query would work anyway. I think the syntax you are looking for is "id IN :Trigger.newmap.keyset()".
     
  4. One other small thing. SOQL queries do not return deleted records (unless you specifically use the "ALL ROWS" keyword) so you do not need the "IsDeleted = false" condition.

 

Hope this helps.

 

Regards

MellowRen

All Answers

MellowRenMellowRen

EUS

 

Note: You have posted this on the wrong board, you should put it in the Apex Code area for better responses. Not sure if you can swap it now.

 

If you simply want to prevent any SetUp object from being created unless none currently exists then this should do it (sorry I can't test but it should be close):

 

trigger NewSetUpRecord on SetUp__c (before insert) {
    Integer suCount = [SELECT count() FROM SetUp__c LIMIT 1];
    if (suCount > 0) {
        for (SetUp__c aSUObject : trigger.new) {
            aSUObject.Name.addError('An active object already exists'); //assuming there is a field called 'Name'.
        }
    }
}

 

This should even work for a mass data load—but you should test. Does it do what you need? Or am I misreading your question?

 

A few comments to help you see what you did:

 

  1. A before trigger allows you to modify/validate data before Salesforce commits the record to the database. Your trigger never actually stops the record from being saved (that is what the addError method does). In fact, had your code ever decided that it was OK to save it would have executed the INSERT command, which would have re-fired this trigger (before the save) which would have become infinitely recursive and eventually generate a Salesforce error.
     
  2. That being said you would not get this infinite loop because your SOQL query would not be returning any results. You are trying to find all existing records whose unique ID is the same as the ID of the records you are about to insert.  :-)
     
  3. Plus, and I could be wrong here, assuming unique IDs weren't unique, I don't think that query would work anyway. I think the syntax you are looking for is "id IN :Trigger.newmap.keyset()".
     
  4. One other small thing. SOQL queries do not return deleted records (unless you specifically use the "ALL ROWS" keyword) so you do not need the "IsDeleted = false" condition.

 

Hope this helps.

 

Regards

MellowRen

This was selected as the best answer
EUSEUS

Hi MellowRen,

 

Thanks for you answer!   You mention this should even work for a mass data load—  so let me ask you something:  Where the error messages would be placed on a batch mass data load? ... Where should I access them to see what is going on?

 

Thanks a lot!

EUS

MellowRenMellowRen

EUS

 

It would depend on the tool you are using for mass insert. The DataLoader (and LexiLoader) creates an error report as a csv file. The Excel Connector highlights records that couldn't be inserted and puts an Excel comment (little red triangle in top right of cell) in the ID column of each row.

 

Other tools would have different ways of doing it.

 

Regards

MellowRen

EUSEUS

Thanks again!