Skip to content

Trabajando con registros de Salesforce usando SOQL y DML ☁️

Esta es una traducción que desde EGA Futura ofrecemos como cortesía a toda la Ohana y comunidad de programadores , consultores , administradores y arquitectos de Salesforce para toda Iberoamérica .

El enlace a la publicación original, lo encontrarás al final de este artículo.

Trabajar con registros de Salesforce utilizando SOQL y DML | Blog de desarrolladores de Salesforce

SOQL (lenguaje de consulta de objetos de Salesforce) y DML (lenguaje de manipulación de datos) son los lenguajes utilizados en Salesforce para leer y modificar registros, respectivamente. En esta publicación de blog, exploraremos cómo usarlos en Apex, incluidas las mejores prácticas para evitar alcanzar los límites del gobernador. Esto será particularmente útil para los desarrolladores que son nuevos en el desarrollo de Salesforce o para aquellos que necesitan una actualización sobre estos temas.

Multiusuario en Salesforce

Antes de sumergirse en SOQL y DML, es importante comprender primero cómo se almacenan sus registros en Salesforce. La base de datos que contiene sus registros detrás de escena en realidad no contiene una tabla SQL para cada uno de sus objetos estándar y personalizados. La base de datos almacena registros en una base de datos multiinquilino, una base de datos que almacena datos y metadatos de múltiples inquilinos de forma estandarizada. La base de datos contiene tablas genéricas para almacenar registros de objetos estándar y personalizados.

Me gusta especialmente la siguiente imagen de una sesión anterior de Dreamforce que ayuda a ilustrar cómo se almacenan los registros de diferentes inquilinos:

También me gusta la explicación de multiusuario en la página wiki de arquitectura multiusuario y la guía Mejores prácticas para implementaciones con grandes volúmenes de datos .

Como puede imaginar, un desarrollador de Salesforce no puede usar SQL para acceder a estas tablas directamente por razones de seguridad. En su lugar, lee datos escribiendo consultas SOQL que el optimizador de consultas traduce de forma transparente a las consultas SQL correspondientes. A diferencia de otros lenguajes de base de datos, los datos no se pueden modificar mediante SOQL. Tenemos otro lenguaje para hacer eso, que es DML.

Modelo de datos de ejemplo

Para ilustrar cómo funcionan SOQL y DML, usaremos un par de objetos personalizados en los ejemplos de código que se muestran más adelante en esta publicación. Tendremos un objeto personalizado Species__c para representar especies de plantas y tendremos un objeto personalizado Plant__c para representar plantas que pertenecen a una determinada especie.


En Salesforce, relaciona objetos mediante relaciones de búsqueda o maestro-detalle . Estos campos son equivalentes a lo que se conoce en otros lenguajes de base de datos como clave externa, un campo que hace referencia a otro objeto. Esto significa que el objeto Plant__c tendrá una relación de búsqueda con Species__c (su padre).

Lectura de datos con SOQL

Comencemos hablando de SOQL. La siguiente es una consulta SOQL simple que usamos para leer registros para un objeto personalizado llamado Plant__c :

2021-01-01 ORDER BY Acquisition_Date__c LIMIT 3″>

Examinemos las diferentes palabras clave utilizadas en la consulta:

  • SELECT : se utiliza para indicar los campos que desea recuperar. El único que se devuelve por defecto es el campo Id . Puede SELECT FIELDS(STANDARD) para recuperar todos los campos estándar para los que el usuario tiene permisos. Eche un vistazo a todas las opciones disponibles para la función y las API en las que son compatibles.
  • FROM : la tabla principal de la que queremos recuperar los registros
  • WHERE : se utiliza para especificar las condiciones del filtro.
  • ORDER BY : se utiliza para ordenar los resultados por un campo específico
  • LIMIT : para limitar el número de resultados devueltos. Sugerencia: el uso LIMIT 1 le permite asignar el resultado en Apex a una única variable de registro. Solo use esta opción si está 100% seguro de que el registro siempre estará allí.

El siguiente es el resultado de esta consulta en una organización en la que creé algunos datos de muestra:

Puede ejecutar consultas con fines de depuración en Developer Console, o preferiblemente en VSCode después de haber instalado el paquete de extensión de Salesforce . En VSCode existen diferentes opciones para hacerlo. La opción preferida y más sencilla es utilizar SOQL Builder , una herramienta para crear y ejecutar consultas visualmente. También puede ejecutar una consulta escrita seleccionándola en el texto o introduciéndola en línea en la barra de comandos .


Sin embargo, donde normalmente usará consultas en producción es en su código Apex. Los objetos estándar y personalizados (también otros tipos de objetos, como los objetos externos) tienen un tipo de datos equivalente en Apex. Por ejemplo, tener un objeto Species__c implica que hay una clase Species__c que representa objetos de ese tipo y que contiene todos los campos del objeto Species__c . También hay una clase sObject genérica que puede usar para cualquier tipo de objeto. Puede construir estos tipos usted mismo o usarlos para almacenar los registros devueltos por una consulta SOQL:

Así es como llamamos a nuestra consulta SOQL desde Apex, encerrándola entre corchetes y asignando el valor devuelto a una List<sObject> o List<ConcreteObject__c> :

<dx-code-block title language code-block="// Executing a query and storying its returned value
List plants = [SELECT Name, Acquisition_Date__c FROM Plant__c WHERE Acquisition_Date__c > 2021-01-01];»>

En la consulta anterior, especificamos todos los valores que queríamos usar, como la fecha de adquisición para filtrar o el número de registro para limitar. Pero, ¿y si no conoce esos valores de antemano? En ese caso, puede vincular las variables de Apex mediante dos puntos ( : de la siguiente manera:

<dx-code-block title language code-block="// Binding an Apex variable
Date acquisitionDate = Date.newInstance(2021,01,01);
List plants = [SELECT Name, Acquisition_Date__c FROM Plant__c WHERE Acquisition_Date__c > :acquisitionDate];»>

El resultado en este caso sería exactamente el mismo, pero la variable acquisitionDate se evaluaría en tiempo de ejecución.

Nota: En Apex, asegúrese de incluir WITH SECURITY_ENFORCED (ver documentos ) en sus consultas, para hacer cumplir la verificación de permisos de seguridad a nivel de campo y objeto.

Traer registros relacionados con consultas de relación

Analicemos ahora cómo puede incorporar datos de registros relacionados en sus consultas SOQL. Esta es probablemente la diferencia más notable con otros lenguajes de consulta. En SOQL, ejecuta consultas en una sola tabla y luego tiene mecanismos para traer datos relacionados como parte de la consulta. Para hacer eso, los objetos necesitan tener una relación. Concretamente, puedes:

  • Consultar a un niño y traer sus datos principales (consulta de niño a padre)
  • Consultar a un padre y traer los datos de sus hijos (consulta de padre a hijo)

Esto significa que en SOQL se pueden realizar uniones como en otros lenguajes de consulta, pero usando una sintaxis diferente y siempre en base a una clave foránea (relación). Esta decisión de diseño se tomó para aumentar el rendimiento en el momento en que el optimizador de consultas traduce las consultas a SQL.

Consultas de relación de hijo a padre

Este tipo de consultas le permiten ejecutar la consulta principal en un objeto secundario y traer sus datos principales como parte del resultado.

Para poder hacer referencia al padre en la parte SELECT , necesitaremos usar el nombre de la API que representa la relación con el padre. En nuestro caso, al ser un objeto personalizado, será el nombre del campo de relación sustituyendo __c por __r . Para objetos estándar, solo use el nombre de la API del campo de relación.

<dx-code-block title language code-block="List plants = [SELECT Name, Acquisition_date__c, Species__r.Name FROM Plant__c];»>

Este es el resultado que obtuve para mi organización:

Si desea obtener información sobre las relaciones de objetos estándar, eche un vistazo a los diferentes modelos de datos de aplicaciones en el sitio de Salesforce Architects.

Consultas de relación padre-hijo

Este tipo de consultas le permiten ejecutar la consulta principal en un objeto principal y traer los datos de sus hijos como parte del resultado.

Para poder hacer referencia a la lista de elementos secundarios en la parte SELECT , necesitaremos usar el nombre de la relación secundaria definido en el campo de relación más __r , o solo el nombre de la relación secundaria para los objetos estándar. En este caso, como el padre puede tener varios hijos, necesitaremos usar una subconsulta.


Por ejemplo, en nuestro caso, podemos traer todas nuestras especies con sus plantas hijas:

<dx-code-block title language code-block="List species = [SELECT Name, (SELECT Name FROM Plants__r) FROM Species__c];»>

El resultado:

Es decir, ¡tengo dos plantas de Jazmín, una Pothos y dos Aloe Vera en mi terraza!

Para manejar el resultado en Apex, tenga en cuenta que el campo de relación devuelto contendrá una lista de hijos:

Hacer más con los campos de relación

Hay mucho más que podemos hacer en SOQL. Por ejemplo, podríamos usar campos de relación principal en la parte WHERE para filtrar por valor(es) de campo principal:

<dx-code-block title language code-block="List plants = [SELECT Name, Acquisition_date__c FROM Plant__c WHERE Species__r.Name = ‘Aloe Vera’];»><dx-code-block title language code-block="List speciesNames = new List{‘Aloe Vera’,’Jasmine’}; // Can also be a Set
List plants = [SELECT Name, Acquisition_date__c FROM Plant__c WHERE Species__r.Name IN :speciesNames];»>

O también podríamos usar una subconsulta en la parte WHERE para filtrar por hijos relacionados:

<dx-code-block title language code-block="List plants = [SELECT Name, Acquisition_date__c FROM Plant__c WHERE Species__c IN (SELECT Id FROM Species__c WHERE Name IN (‘Aloe vera’,’Jasmine’))];»>

Construcción de consultas en tiempo de ejecución con SOQL dinámico

Hasta ahora, hemos usado SOQL estático para ejecutar nuestras consultas. Pero a veces, debe construir la consulta en tiempo de ejecución (en forma de cadena) y luego ejecutarla como una consulta dinámica . Así es como lo haces:

<dx-code-block title language code-block="String myQuery = 'SELECT Name FROM Species__c';
List sobjList = Database.query(myQuery); // Can be assigned to List too»>

Se prefieren las consultas estáticas cuando es posible, ya que se evalúan en el momento de la compilación, lo que evita consultas mal construidas y ataques de inyección de SOQL. Para evitar la inyección de SOQL en consultas dinámicas, vincule siempre el valor proporcionado por el usuario utilizando la notación de dos puntos.

Aprovechar el poder de las consultas agregadas

Las consultas agregadas le permiten acumular y resumir registros. Por ejemplo, puedo contar la cantidad de registros que coinciden con una condición específica, como la cantidad de plantas de Aloe Vera que tengo:

O puedo usar la función AVG() para calcular los valores promedio de temperatura máxima que admite mi especie:

<dx-code-block title language code-block="List groupedResults = [SELECT AVG(Max_Temperature__c) avgTemp FROM Species__c]; for (AggregateResult ar : groupedResults) { System.debug(‘Average Temperature: ‘ + ar.get(‘avgTemp’));
}»>

Esto es lo que obtuve como resultado:

Las consultas agregadas se vuelven aún más poderosas cuando se usa GROUP BY . Por ejemplo, así es como calculo los valores promedio de temperatura máxima que soporta mi especie, agrupados por tipo de especie (ornamental o comestible):

<dx-code-block title language code-block="List groupedResults = [SELECT Type__c, AVG(Max_Temperature__c) avgTemp FROM Species__c GROUP BY Type__c]; for (AggregateResult ar : groupedResults) { System.debug(‘Type__c: ‘ + ar.get(‘Type__c’)); System.debug(‘Average Temperature: ‘ + ar.get(‘avgTemp’));
}»>

En este caso, obteniendo:

Modificación de registros con DML

A continuación, echemos un vistazo a cómo manipula los registros en Apex. Para ello, en lugar de utilizar SOQL, utilizamos DML , nuestro lenguaje de manipulación de datos. Gracias al uso de DML para la modificación de registros, podemos prevenir fallas de inyección de SOQL asociadas a estas operaciones.

Con DML, puede insert , update , upsert , delete e incluso undelete y merge registros utilizando esas palabras clave antes de un registro o una lista de registros para manipular. Aquí hay unos ejemplos:

Manejo de excepciones y control de transacciones para operaciones DML

El manejo de excepciones es un aspecto importante a tener en cuenta al realizar operaciones DML. Si una operación DML falla, el tiempo de ejecución de Apex lanza una DMLException . Esto puede suceder, por ejemplo, cuando el sObject a modificar contiene valores incorrectos o cuando no se cumple una validación en un disparador. Si no se manejan las excepciones, Salesforce revierte automáticamente todas las operaciones DML que ocurrieron durante esa transacción .

Puede manejar excepciones y realizar reversiones totales o parciales usted mismo utilizando los mecanismos de control de transacciones de Apex.

En este caso, si el registro Species__c se insertó correctamente pero la creación del registro Plant__c falló, el registro Species__c aún se creará. La reversión automática de Salesforce no sucedió; en su lugar, revertimos manualmente la base de datos al estado que tenía después de que se creó el registro Species__c . Al hacer eso, revertimos cualquier cambio realizado por los activadores y automatizaciones que se ejecutaron durante la operación de inserción de la planta antes de que ocurriera la falla. De esa manera, mantuvimos la integridad de los datos.

Modificación de registros en tiempo de ejecución con DML dinámico

De la misma manera que construye consultas dinámicas, puede crear registros dinámicamente y luego manipularlos usando DML. Esta opción puede ser interesante cuando no se sabe el nombre del objeto o los campos a modificar de antemano.

Límites del gobernador y aumento de volumen

Por último, cubramos un concepto importante que los desarrolladores de Salesforce deben comprender y tener en cuenta al escribir código. El concepto de tenencia múltiple no solo se aplica a la base de datos. Toda su instancia de Salesforce se ejecuta en una infraestructura compartida de forma segura con otros inquilinos. Es por eso que Salesforce evita que su código personalizado monopolice los recursos y, lo que más me gusta del desarrollo de Salesforce, necesita escribir un código óptimo, porque si no lo hace, alcanzará fácilmente los límites del gobernador . Algunos límites reguladores que se aplican a las operaciones SOQL y DML son:

  • Puede ejecutar como máximo 100 consultas SOQL dentro de una transacción
  • Puede ejecutar como máximo 150 declaraciones DML en una transacción

Esto significa que para minimizar la cantidad de consultas SOQL y operaciones DML que su código ejecuta dentro de una transacción, es una buena práctica:

  • Realice siempre esas operaciones sobre colecciones de registros en lugar de sobre registros únicos (lo que llamamos "agrupar").
  • Nunca, nunca, nunca ejecute SOQL o DML dentro de un ciclo
  • Use SOQL para bucles (más eficiente) cuando sea posible

Sugerencia: sus bloques catch no podrán manejar las excepciones de límite del regulador y siempre se comportarán como excepciones no controladas, lo que resultará en una reversión completa.

SOSL

En una nota final, hay otro lenguaje que se usa para construir consultas de texto basadas en búsqueda llamado SOSL (Lenguaje de búsqueda de objetos de Salesforce), sin embargo, no cubriremos SOSL en esta publicación de blog.

Recursos y próximos pasos

En esta publicación de blog, aprendió sobre los aspectos más importantes que un desarrollador de Salesforce debe conocer para comenzar a escribir código Apex que funcione con registros de Salesforce. Hemos visto cómo funciona SOQL para leer registros y cómo modificar registros usando DML.

Algunas entradas de blog relacionadas:

Y si prefiere ponerse manos a la obra, diríjase a Trailhead y aborde los siguientes módulos:

Autores

Alba Rivas trabaja como Principal Developer Advocate en Salesforce. Actualmente se enfoca en el desarrollo de Lightning Web Components y Slack. Puedes seguirla en Twitter @AlbaSFDC .

Obtenga las últimas publicaciones de blog de desarrolladores de Salesforce y episodios de podcast a través de Slack o RSS.

Agregar a Slack Suscríbete a RSS

Esta es una traducción realizada por EGA Futura, y este es el link a la publicación original: https://developer.salesforce.com/blogs/2022/08/working-with-salesforce-records-using-soql-and-dml.html

Entradas recomendadas