5

I have to generate a Unique number for every record in a object.I can't use the Auto-number and SFDC ID of the record.

It's a kind of External ID that external System can use to identify the records.

5
  • 11
    Can you explain why you can't add just an extra auto-number field to do this? That is by far the simplest solution.
    – Keith C
    Aug 8, 2014 at 18:08
  • is there some particular format that the external id must adhere to?
    – cropredy
    Aug 8, 2014 at 18:34
  • Do you care if they're in order? Or just that they're unique?
    – sfdcfox
    Aug 8, 2014 at 18:45
  • Similar question/answer can be found here: salesforce.stackexchange.com/questions/4289/…
    – Jenny B
    Aug 8, 2014 at 23:20
  • @jjbennett530 Numbers with no gaps - the focus of your link - is extra hard; unclear yet whether that is required or not.
    – Keith C
    Aug 9, 2014 at 0:25

2 Answers 2

3

If you really, really need to do this, you could try this:

String s = record.createDateTime.format(); // or some other datetime

Blob hash = Crypto.generateDigest('MD5', Blob.valueOf(s));
String uniqueString = EncodingUtil.convertToHex(hash);

return uniqueString;

You'd need to use it in an oncreate trigger and update the record with this value. If the string was too long, you could just chop it off at some point using theString.substring(start,numChars);

1
  • I have a similar problem, with the parallel concurrence in the creation of of a custom setting record. Has been violated the the unique name rule and has been created two records with same name, which create problems in update etc...
    – Klodj_Meta
    Oct 30, 2014 at 12:43
3

Elaborating on Caspar Harmer's answer:

Blob hash = Crypto.generateDigest('MD5', Blob.valueOf(s)); is very expensive CPU Time wise.

The following test timed out for me, as did a loop of 1000:

@isTest
private static void testIdUniquenessMultipleCalls  () {
    Set<String> ids = new Set<string>();
    for(Integer i = 0; i < 10000; i++) {
        ids.add(Utility.getUniqueId());
    }
    system.assertEquals(10000,ids.size(),'consecutive calls must produce distinct Ids');
}

I always received a CPU Time Limit exception.

Here's a version that passes the test:

public static String getUniqueId(){
    String milliseconds = String.ValueOf(System.Now().getTime()); //unix timestamp
    Blob pseudoHash = Blob.ValueOf(milliseconds + String.ValueOf(Crypto.getRandomInteger()));
    String uniqueString = EncodingUtil.convertToHex(pseudoHash);
    uniqueString = uniqueString.length() > 255 ? uniqueString.substring(0,255) : uniqueString;
    return uniqueString;
}
1
  • If I grab the first 18 chars of <uniqueString>, as you might do for an external ID field and run it in a loop, I see duplicates. This doesn't happen when I use Crypto.generateAesKey() and convert to hex. Dec 13, 2021 at 3:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .