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

      Deleting Records with DML

      Deleting Records with DML

      insert creates a record, update changes one, and delete removes it. Deleting is
      the easiest of the three to write and the hardest to get right, because it is the only
      one that can take other records with it, and the only one something else in the org can
      refuse.

      Find the Record First

      A delete works on a record Id, so the record has to have one. The usual shape is the
      same one update uses: query the record, then delete what the query returned.

      List<Contact> rows = [SELECT Id FROM Contact WHERE Email = :email];
      delete rows;
      

      The query hands you records that already carry their Ids, so there is nothing else to
      prepare. Delete the records the query returned, not their Ids: delete cannot take a
      List<Id> and fails to compile with DML requires SObject or SObject list type.

      A Record With No Id Throws ListException

      If you delete a record you built yourself and never inserted, the Id is null, and the
      delete fails:

      System.ListException: Invalid id at index 0: null

      Note the exception type. It is a ListException, not a DmlException, so a
      catch (DmlException e) block does NOT catch it. Only a general catch (Exception e)
      does. Probed on the validation org: e instanceof DmlException is false and
      e instanceof ListException is true.

      A record that has an Id but does not exist in the database fails differently: that one
      is a DmlException carrying INVALID_CROSS_REFERENCE_KEY, invalid cross reference id.

      A Delete Can Be Refused

      Sometimes the delete itself is fine and the org says no. The error looks like this:

      DELETE_FAILED, Your attempt to delete Alpine Private Bank could not be completed because it is associated with the following maintenance requests.: 00007635

      That means something else is holding the record: a validation rule, a trigger, or a
      child record that cannot go without it. This is worth knowing before you build
      something around a delete. On the production grading org, an Account trigger creates a
      Case for every new Account, and that Case blocks the Account delete — and because
      Case cannot be queried there, it cannot be removed first either. On that same org a
      Contact deletes without any trouble.

      So a delete that works on your sandbox may not work on the org you are graded in. Test
      the delete on the object you actually intend to delete.

      Deleting a Parent Takes Its Children With It

      Deleting an Account also deletes the Contacts and Opportunities that pointed at it.
      Those are lookup relationships, and the child rows go with the parent. Probed on the
      validation org: deleting an Account that had one Contact and one Opportunity left zero
      of each behind.

      This is the reason to think before you delete: the rows you remove are not only the
      row you asked about.

      The API Form and Partial Success

      Database.delete(record) does the same thing as the statement and hands you a
      Database.DeleteResult with isSuccess() and getErrors(). Pass false as the
      second argument to keep going when one row fails:

      List<Database.DeleteResult> results = Database.delete(rows, false);
      

      With false the good rows are deleted and the failures come back in the result.
      Without it, one bad row rolls back the whole statement. Note the return type: the
      single-record form returns one Database.DeleteResult, while the list form returns a
      List<Database.DeleteResult>.

      Common Mistakes

      The first mistake is deleting a record you never inserted, which throws the
      ListException above. The second is catching DmlException and assuming that covers
      it. The third is deleting a parent record without knowing that its children go with
      it. A fourth, quieter one: a Contact Email is not unique on this org, so deleting by
      email can remove more than one row.

      Why This Matters

      A delete is the only DML operation you cannot undo by changing the record back. Soft
      delete exists for exactly this reason: it hides the row instead of removing it, so a
      mistake can be reversed.

      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