Skip to main content

Manipular registros con DML

Objetivos de aprendizaje

Después de completar esta unidad, podrá hacer lo siguiente:

  • Usar DML para insertar, actualizar y eliminar registros.
  • Realizar declaraciones DML de forma masiva.
  • Usar la alteración para insertar o actualizar un registro.
  • Capturar una excepción DML.
  • Usar un método de base de datos para insertar registros nuevos con la opción de validez parcial y procesar los resultados.
  • Saber cuándo usar declaraciones DML y cuándo usar métodos de base de datos.
  • Realizar operaciones DML en registros relacionados.
Nota

Nota

¿Es su idioma de aprendizaje español (LATAM)? Comience el reto en un Trailhead Playground en español (LATAM) y utilice las traducciones entre paréntesis para navegar. Copie y pegue solo los valores en inglés, ya que las validaciones del reto dependen de los datos en ese idioma. Si no aprueba el reto en su organización en español (LATAM), recomendamos que (1) cambie la configuración local a Estados Unidos, (2) cambie el idioma a inglés (según estas instrucciones) y, luego, (3) haga clic en el botón “Check Challenge” (Comprobar el reto) nuevamente.

Consulte la insignia Trailhead en su idioma para obtener más información sobre cómo aprovechar la experiencia de Trailhead en otros idiomas.

Manipular registros con DML

Cree y modifique registros en Salesforce mediante el uso del lenguaje de manipulación de datos (DML, Data Manipulation Language). DML es un método sencillo para gestionar registros mediante una serie de declaraciones simples para insertar, actualizar, combinar, eliminar y restaurar registros.

Dado que Apex es un lenguaje centrado en los datos y se guarda en la plataforma Lightning, tiene acceso directo a sus datos en Salesforce. A diferencia de otros lenguajes de programación que requieren una configuración adicional para la conexión con fuentes de datos, en el caso de DML de Apex, se simplifica la gestión de registros. Mediante la llamada a declaraciones DML, puede realizar rápidamente operaciones en sus registros de Salesforce. En este ejemplo se agrega la cuenta Acme a Salesforce. En primer lugar se crea una cuenta sObject y, a continuación, se pasa como un argumento a la declaración insert, lo que conserva el registro en Salesforce.

// Create the account sObject
Account acct = new Account(Name='Acme', Phone='(415)555-1212', NumberOfEmployees=100);
// Insert the account by using DML
insert acct;

Declaraciones DML

Están disponibles las siguientes declaraciones DML.

  • Insert (insertar)
  • update (actualizar)
  • upsert (alterar)
  • delete (eliminar)
  • undelete (recuperar)
  • merge (combinar)

Cada declaración DML acepta un único sObject o una lista (o conjunto) de sObjects. La realización de operaciones en una lista de sObjects es un método más eficiente para procesar los registros.

Todas estas declaraciones, a excepción de un par, son operaciones de base de datos conocidas. Las declaraciones upsert y merge son específicas de Salesforce y pueden ser de gran utilidad.

Con la operación DML upsert, se crean registros y se actualizan los registros de sObject en una sola declaración mediante un campo especificado para determinar la presencia de objetos existentes o el campo de Id. si no se ha especificado ningún campo.

La declaración merge combina hasta tres registros del mismo tipo de sObject en uno de los registros mediante la eliminación de los demás y la reorganización jerárquica de todos los registros relacionados.

Asignación automática de campos de Id. a registros nuevos

Al insertar registros, el sistema asigna un Id. a cada registro. Además de garantizar la persistencia del valor de Id. en la base de datos, el valor de Id. se completa automáticamente en la variable de sObject usada como argumento en la llamada a DML.

En este ejemplo se muestra cómo obtener el Id. en el sObject correspondiente a la cuenta insertada.

// Create the account sObject
Account acct = new Account(Name='Acme', Phone='(415)555-1212', NumberOfEmployees=100);
// Insert the account by using DML
insert acct;
// Get the new ID on the inserted sObject argument
ID acctID = acct.Id;
// Display this ID in the debug log
System.debug('ID = ' + acctID);
// Debug log result (the ID will be different in your case)
// DEBUG|ID = 001D000000JmKkeIAF







Nota

Más allá de los fundamentos

Dado que la variable del ejemplo incluye el Id. después de la llamada a DML, puede reutilizar esta variable de sObject para realizar operaciones DML adicionales, ya que el sistema puede asignar la variable de sObject al registro correspondiente mediante la coincidencia con el Id.

Puede recuperar un registro de la base de datos para obtener sus campos, incluido el campo de Id., pero esta acción no se puede realizar con DML. Debe escribir una consulta mediante SOQL. Obtendrá más información sobre SOQL en otra unidad.

DML masivo

Puede realizar operaciones DML en un solo sObject o bien de forma masiva en una lista de sObjects. Se recomienda realizar operaciones DML masivas, ya que ayuda a evitar alcanzar los límites reguladores, como el límite de DML de 150 declaraciones por transacción de Apex. Este límite se establece para garantizar un correcto acceso a los recursos compartidos en la Plataforma Lightning. La realización de una operación DML en una lista de sObjects se corresponde con una sola declaración DML, no como una única declaración para cada sObject.

En este ejemplo se insertan contactos de forma masiva mediante la inserción de una lista de contactos en una sola llamada. A continuación, estos contactos también se actualizan de forma masiva.

  1. Ejecute este miniprograma en la consola de desarrollador mediante Apex anónimo.
    // Create a list of contacts
    List<Contact> conList = new List<Contact> {
        new Contact(FirstName='Joe',LastName='Smith',Department='Finance'),
            new Contact(FirstName='Kathy',LastName='Smith',Department='Technology'),
            new Contact(FirstName='Caroline',LastName='Roth',Department='Finance'),
            new Contact(FirstName='Kim',LastName='Shain',Department='Education')};
    // Bulk insert all contacts with one DML call
    insert conList;
    // List to hold the new contacts to update
    List<Contact> listToUpdate = new List<Contact>();
    // Iterate through the list and add a title only
    //   if the department is Finance
    for(Contact con : conList) {
        if (con.Department == 'Finance') {
            con.Title = 'Financial analyst';
            // Add updated contact sObject to the list.
            listToUpdate.add(con);
        }
    }
    // Bulk update all contacts with one DML call
    update listToUpdate;
  2. Inspeccione los contactos recién creados en su organización.
    Dos de los contactos del departamento de finanzas deben tener sus puestos de trabajo completados con Financial analyst (Analista financiero).

Alteración de registros

Si tiene una lista con una combinación de registros nuevos y existentes, puede procesar inserciones y actualizaciones para todos los registros de la lista mediante la declaración upsert. La alteración permite evitar la creación de registros duplicados y ahorrar tiempo, ya que no necesita determinar qué registro existe primero.

La declaración upsert determina la coincidencia de los sObjects y los registros existentes mediante la comparación de los valores de un solo campo. Si no especifica ningún campo al llamar a esta declaración, la declaración upsert usa el Id. de sObject para determinar la coincidencia de sObject y los registros existentes de Salesforce. De forma alternativa, puede especificar un campo para la coincidencia. En el caso de los objetos personalizados, especifique un campo personalizado marcado como Id. externo. En el caso de los objetos estándar, puede especificar cualquier campo con la propiedad idLookup establecida como verdadera. Por ejemplo, el campo Email del contacto o usuario tiene la propiedad idLookup establecida. Para comprobar la propiedad de un campo, consulte Referencia de objetos para Salesforce y Plataforma Lightning.

Sintaxis de upsert

upsert sObject | sObject[]


upsert sObject | sObject[] field

El campo opcional es un token de campo. Por ejemplo, para especificar el campo MyExternalID, la declaración es:

upsert sObjectList Account.Fields.MyExternalId;

En el caso de upsert, se usan la clave principal del registro de sObject (Id.), un campo idLookup o un campo de Id. externo para determinar si se debe crear un registro nuevo o actualizar uno existente:

  • Si la clave no coincide, se crea un registro de objeto.
  • Si la clave coincide una vez, se actualiza el registro de objeto existente.
  • Si la clave coincide varias veces, se genera un error y el registro de objeto no se inserta ni actualiza.

En este ejemplo se muestra cómo upsert actualiza un registro de contacto existente e inserta un contacto nuevo en una sola llamada. Esta llamada a upsert actualiza el contacto Josh existente e inserta el contacto nuevo Kathy.

Nota

Nota

La llamada a upsert usa el Id. para establecer la coincidencia con el primer contacto. La variable josh se reutiliza para la llamada a upsert. Dado que esta variable ya se ha completado con el Id. de registro de la llamada a insert anterior, no es necesario establecer el Id. de forma explícita en este ejemplo.

  1. Ejecute este miniprograma en la ventana de ejecución anónima de la consola de desarrollador.
    // Insert the Josh contact
    Contact josh = new Contact(FirstName='Josh',LastName='Kaplan',Department='Finance');
    insert josh;
    // Josh's record has been inserted
    //   so the variable josh has now an ID
    //   which will be used to match the records by upsert
    josh.Description = 'Josh\'s record has been updated by the upsert operation.';
    // Create the Kathy contact, but don't persist it in the database
    Contact kathy = new Contact(FirstName='Kathy',LastName='Brown',Department='Technology');
    // List to hold the new contacts to upsert
    List<Contact> contacts = new List<Contact> { josh, kathy };
    // Call upsert
    upsert contacts;
    // Result: Josh is updated and Kathy is created.
  2. Inspeccione todos los contactos de su organización.
    Su organización tendrá un solo registro Josh Kaplan y no dos, ya que la operación de alteración (upsert) ha detectado y actualizado el registro existente en lugar de crear un registro de contacto nuevo. Además, se incluirá un registro de contacto Kathy Brown.

De forma alternativa, puede especificar un campo para los registros coincidentes. Este ejemplo utiliza el campo Email en Contacto porque tiene la propiedad idLookup establecida. En el ejemplo se inserta el contacto Jane Smith y se crea un segundo sObject de contacto, se completa con el mismo email y, a continuación, se llama a upsert para actualizar el contacto mediante el campo Email para determinar la coincidencia.

Nota

Nota

Si se usara insert en este ejemplo en lugar de upsert, se habría insertado un contacto Jane Smith duplicado.

  1. Ejecute este miniprograma en la ventana de ejecución anónima de la consola de desarrollador.
    Contact jane = new Contact(FirstName='Jane',
                             LastName='Smith',
                             Email='jane.smith@example.com',
                             Description='Contact of the day');
    insert jane;
    // 1. Upsert using an idLookup field
    // Create a second sObject variable.
    // This variable doesn’t have any ID set.
    Contact jane2 = new Contact(FirstName='Jane',
                             LastName='Smith',
                             Email='jane.smith@example.com',
                             Description='Prefers to be contacted by email.');
    // Upsert the contact by using the idLookup field for matching.
    upsert jane2 Contact.fields.Email;
    // Verify that the contact has been updated
    System.assertEquals('Prefers to be contacted by email.',
                       [SELECT Description FROM Contact WHERE Id=:jane.Id].Description);
  2. Inspeccione todos los contactos de su organización.
    Su organización solo tendrá un contacto Jane Smith con la descripción actualizada.

Eliminar registros

Puede eliminar registros persistentes mediante la declaración delete. Los registros eliminados no se eliminan de forma permanente de Plataforma Lightning, sino que se envían a la papelera de reciclaje durante 15 días y se pueden restaurar desde ahí.

En este ejemplo se muestra cómo eliminar todos los contactos con el apellido Smith. Si realiza las acciones del ejemplo en el caso de DML masivo, su organización ya debería tener dos contactos con el apellido Smith. Ejecute este miniprograma en la consola de desarrollador mediante Apex anónimo y, a continuación, verifique que ya no hay contactos con el apellido Smith.

Contact[] contactsDel = [SELECT Id FROM Contact WHERE LastName='Smith'];
delete contactsDel;
Nota

Nota

Este miniprograma incluye una consulta para recuperar los contactos (consulta SOQL). Obtendrá más información sobre SOQL en otra unidad.

Excepciones de declaraciones DML

Si una operación DML genera un error, devuelve una excepción del tipo DmlException. Puede capturar las excepciones del código para controlar los errores.

En este ejemplo se produce una excepción del tipo DmlException porque se intenta insertar una cuenta sin el campo Nombre obligatorio. La excepción se captura en un bloque de captura.

try {
    // This causes an exception because
    //   the required Name field is not provided.
    Account acct = new Account();
    // Insert the account
    insert acct;
} catch (DmlException e) {
    System.debug('A DML exception has occurred: ' +
                e.getMessage());
}



Métodos de base de datos

Apex contiene la clase de base de datos integrada, lo que proporciona métodos para realizar operaciones DML y reflejar homólogos de declaraciones DML.

Estos métodos de base de datos son estáticos y se llama a ellos en el nombre de clase.

  • Database.insert()
  • Database.update()
  • Database.upsert()
  • Database.delete()
  • Database.undelete()
  • Database.merge()

A diferencia de las declaraciones DML, los métodos de base de datos incluyen un parámetro allOrNone opcional que permite especificar si la operación debe ser correcta parcialmente. Cuando este parámetro se establece en false, si se produce un error en un conjunto parcial de registros, los registros correctos se confirman y los errores se devuelven para los registros incorrectos. Además, no se producen excepciones con la opción de validez parcial.

De este modo, llama al método insert con allOrNone establecido en false (falso).

Database.insert(recordList, false);

Los métodos de base de datos devuelven objetos de resultados que contienen información de validez o error para cada registro. Por ejemplo, las operaciones de inserción y actualización devuelven en cada caso un conjunto de objetos Database.SaveResult.

Database.SaveResult[] results = Database.insert(recordList, false);
Nota

Nota

La alteración devuelve objetos Database.UpsertResult y la eliminación devuelve objetos Database.DeleteResult.

De forma predeterminada, el parámetro allOrNone es true (verdadero), lo que significa que el método de base de datos se comporta como su homólogo de declaración DML y producirá una excepción si se detecta un error.

Las dos declaraciones siguientes son equivalentes a la declaración insert recordList;.

Database.insert(recordList);

Y:

Database.insert(recordList, true);







Nota

Más allá de los fundamentos

Además de estos métodos, la clase de base de datos contiene métodos que no se proporcionan como declaraciones DML. Por ejemplo, se incluyen métodos para el control y la reversión de transacciones, métodos para vaciar la papelera de reciclaje y métodos relacionados con consultas SOQL. Obtendrá más información sobre SOQL en otra unidad.

Ejemplo: Inserción de registros de validez parcial

Vamos a examinar un ejemplo en el que se usan métodos de base de datos. Este ejemplo se basa en el ejemplo de DML masivo, pero sustituye a la declaración DML con un método de base de datos. El método Database.insert() se llama con la opción de validez parcial. Un contacto de la lista no tiene ningún campo a propósito y producirá un error dado que el contacto no se puede guardar sin el campo obligatorio LastName. Se confirman tres contactos y el contacto sin ningún campo genera un error. La última parte de este ejemplo es iterativa en los resultados devueltos y escribe mensajes de depuración en el registro de depuración.

  1. Ejecute este ejemplo en la ventana de ejecución anónima de la consola de desarrollador.
    // Create a list of contacts
    List<Contact> conList = new List<Contact> {
            new Contact(FirstName='Joe',LastName='Smith',Department='Finance'),
            new Contact(FirstName='Kathy',LastName='Smith',Department='Technology'),
            new Contact(FirstName='Caroline',LastName='Roth',Department='Finance'),
            new Contact()};
    // Bulk insert all contacts with one DML call
    Database.SaveResult[] srList = Database.insert(conList, false);
    // Iterate through each returned result
    for (Database.SaveResult sr : srList) {
        if (sr.isSuccess()) {
            // Operation was successful, so get the ID of the record that was processed
            System.debug('Successfully inserted contact. Contact ID: ' + sr.getId());
        } else {
            // Operation failed, so get all errors
            for(Database.Error err : sr.getErrors()) {
                System.debug('The following error has occurred.');
                System.debug(err.getStatusCode() + ': ' + err.getMessage());
                System.debug('Contact fields that affected this error: ' + err.getFields());
    	 }
        }
    }
  2. Compruebe los mensajes de depuración (use la palabra clave DEBUG para el filtro).
    Se debe indicar un error y se deben haber insertado tres contactos.

¿Debe usar declaraciones DML o métodos de base de datos?

  • Use las declaraciones DML si desea que cualquier error que se produzca durante el procesamiento masivo de DML se genere como una excepción de Apex que interrumpa de inmediato el flujo del control (mediante el uso de bloques try...catch). Este comportamiento es similar al modo en el que se controlan las excepciones en la mayoría de los lenguajes de procedimientos de base de datos.
  • Use métodos de clase de base de datos si desea permitir la validez parcial de una operación DML masiva (si un registro genera un error, el resto de la operación DML aún puede ser válida). A continuación, su aplicación puede inspeccionar los registros rechazados y posiblemente volver a intentar la operación. Si usa este método, puede escribir código que nunca genere errores de excepción DML. Por el contrario, su código puede usar el conjunto de resultados correspondiente para valorar la validez o los errores. Tenga en cuenta que los métodos de base de datos incluyen además una sintaxis que admite las excepciones producidas de forma similar a las declaraciones DML.

Cree y gestione registros relacionados entre sí mediante relaciones.

Inserción de registros relacionados

Puede insertar registros relacionados con los registros existentes si ya se ha definido una relación entre los dos objetos, como una búsqueda o una relación principal-detalle. Un registro se asocia a un registro relacionado mediante un Id. de clave externa. Por ejemplo, si va a insertar un contacto nuevo, puede especificar el registro de cuenta relacionado del contacto mediante la configuración del valor del campo AccountId.

En este ejemplo se muestra cómo agregar un contacto a una cuenta (registro relacionado) mediante la configuración del campo AccountId del contacto. El contacto y la cuenta están vinculados mediante una relación de búsqueda.

  1. Ejecute este miniprograma en la ventana de código Apex anónimo de la consola de desarrollador.
    Account acct = new Account(Name='SFDC Account');
    insert acct;
    // Once the account is inserted, the sObject will be
    // populated with an ID.
    // Get this ID.
    ID acctID = acct.ID;
    // Add a contact to this account.
    Contact mario = new Contact(
        FirstName='Mario',
        LastName='Ruiz',
        Phone='415.555.1212',
        AccountId=acctID);
    insert mario;
  2. Inspeccione los contactos de su organización.
    Se ha creado una cuenta nueva (SFDC Account) que incluye el contacto Mario Ruiz en la lista relacionada de contactos de la cuenta.

Actualización de registros relacionados

Los campos de los registros relacionados no se pueden actualizar con la misma llamada a la operación DML y requieren una llamada a DML independiente. Por ejemplo, si va a insertar un contacto nuevo, puede especificar el registro de cuenta relacionado del contacto mediante la configuración del valor del campo AccountId. No obstante, no puede cambiar el nombre de la cuenta sin actualizar la cuenta mediante una llamada a DML independiente. De forma similar, al actualizar un contacto, si desea además actualizar la cuenta relacionada del contacto, debe hacer dos llamadas a DML. En el ejemplo siguiente, se actualizan un contacto y su cuenta relacionada mediante dos declaraciones update (actualizar).

// Query for the contact, which has been associated with an account.
Contact queriedContact = [SELECT Account.Name
                          FROM Contact
                          WHERE FirstName = 'Mario' AND LastName='Ruiz'
                          LIMIT 1];
// Update the contact's phone number
queriedContact.Phone = '(415)555-1213';
// Update the related account industry
queriedContact.Account.Industry = 'Technology';
// Make two separate calls
// 1. This call is to update the contact's phone.
update queriedContact;
// 2. This call is to update the related account's Industry field.
update queriedContact.Account;

Eliminación de registros relacionados

La operación delete admite eliminaciones en cascada. Si elimina un objeto principal, elimina también automáticamente los secundarios siempre que cada registro secundario se pueda eliminar.

Por ejemplo, la eliminación de la cuenta creada anteriormente (SFDC Account) eliminará también su contacto relacionado.

  1. Ejecute este miniprograma en la ventana de código Apex anónimo de la consola de desarrollador.
    Account[] queriedAccounts = [SELECT Id FROM Account WHERE Name='SFDC Account'];
    delete queriedAccounts;
  2. Compruebe las cuentas y los contactos de su organización.
    Verá que se han eliminado tanto la cuenta como su contacto relacionado.

Acerca de las transacciones

Las operaciones DML se ejecutan en una transacción. Todas las operaciones DML de una transacción se completan correctamente o si se produce un error en una operación, se revierte toda la transacción y no se confirma ningún dato para la base de datos. El límite de una transacción puede ser un desencadenador, un método de clase, un bloque anónimo de código, una página de Apex o un método de servicio web personalizado. Por ejemplo, si un desencadenador o una clase crean dos cuentas y actualizan un contacto, y la actualización del contacto es incorrecta debido a un error de regla de validación, se revierte toda la transacción y ninguna de las cuentas persiste en Salesforce.

Recursos

Comparta sus comentarios de Trailhead en la Ayuda de Salesforce.

Nos encantaría saber más sobre su experiencia con Trailhead. Ahora puede acceder al nuevo formulario de comentarios en cualquier momento en el sitio de Ayuda de Salesforce.

Más información Continuar a Compartir comentarios