• Lessons Home
Topics
Community
  1. Lessons
  2. DML & Records
  3. DML Basics
  4. Upserting Records with DML

      Upserting Records with DML

      Upserting Records with DML

      insert always creates. update always changes. upsert decides for itself: given a
      key, it creates the record when the key is new and changes it when the key already
      exists. That is the operation an integration needs, because the incoming data does not
      say which of the two it is.

      The Key Decides What Happens

      An upsert needs a field that identifies the record: an external ID field you create
      yourself, or a standard indexed field. Contact.Email is indexed, so it works as a
      key:

      Contact record = new Contact(Email = 'taylor@brightlabs.io', LastName = 'Taylor');
      Database.UpsertResult upsertResult = Database.upsert(record, Contact.Email);
      if (upsertResult.isCreated()) {
      	// there was no Contact with that Email, so one was inserted
      } else {
      	// a Contact with that Email existed, and it was updated
      }
      

      The second argument is the key. Salesforce matches the incoming record against the
      existing rows on that field, and isCreated() tells you which side of the match it
      landed on.

      Not every field can be a key. The key has to be an external ID custom field or a
      standard indexed field, and the error says so plainly:

      Invalid field for upsert, must be an External Id custom or standard indexed field: Name

      Do Not Name the Variable After the Type

      Look closely at the code above: the variable is called record, not contact. That is
      not a style choice. If you write Contact contact = new Contact(...), the name
      Contact inside the method now refers to that VARIABLE, not to the type, so
      Contact.Email reads as the Email of the record you just built. The compiler goes
      looking for an overload that takes a String there and reports:

      Method does not exist or incorrect signature: void upsert(Contact, String) from the type Database

      The message names a method signature that does not exist, which sends you hunting
      through the Database API instead of looking at your own variable name. Name the
      variable something else, or use a fully qualified reference.

      Only the Fields You Set Are Written

      An upsert behaves like an update on the fields it touches. A Contact that already has
      a Phone and an Account keeps both when you upsert it with only an Email and a LastName
      in the record. The fields you leave off the incoming record are left alone on the
      existing row.

      The Trap: The Statement Form

      A bare upsert record; does NOT use your Email as a key. It has no key at all, so it
      matches on the record Id, and a record with no Id is a new record:

      Contact record = new Contact(Email = 'taylor@brightlabs.io', LastName = 'Taylor');
      upsert record;   // creates a SECOND contact with the same email
      

      Probed on the validation org: after that runs, two Contacts share that email. Use the
      two-argument Database.upsert(record, Contact.Email) form when the key is a field
      other than the Id.

      A Blank Key Is an Error

      The key cannot be blank. Upserting a Contact whose Email is null, empty, or only
      spaces throws:

      Upsert failed. First exception on row 0; first error: MISSING_ARGUMENT, Email not specified: []

      So guard the key before you upsert. LastName is required on Contact as well, so a
      blank LastName fails the same way with REQUIRED_FIELD_MISSING.

      Common Mistakes

      The first mistake is the statement form, which quietly creates duplicates. The second
      is naming the variable after the type, which turns the key reference into a compile
      error about a method signature you never wrote. The third is guarding the key but not
      the required fields.

      Why This Matters

      Upsert is how an integration stays idempotent: run the same batch twice and the
      second run changes nothing.

      Apex Code Editor
      Sign in to Submit

      Welcome to Lightning Challenge!

      How It Works

      • • Write your solution in the code editor
      • • Connect your Salesforce org to test
      • • Submit to check if your solution passes
      • • Use hints if you get stuck

      Note

      Complete this lesson challenge to earn points and track your progress. The code editor allows you to implement your solution, and the tests will verify if your code meets the requirements.

      Wally Assistant

      Wally can't hear you

      Please sign in to access the AI Assistant

      Sign In