Novedades en el Query Framework: QueryFilter y QueryHavingFilter

En este nuevo post vamos a ver las novedades que se incluyeron en el framework de consultas a partir de la versión 2012 de Microsoft Dynamics AX.

Para ello, vamos a hablar de las clases QueryHavingFilter y QueryFilter.

QUERYHAVINGFILTER

La clase QueryHavingFilter, como decíamos, ha sido añadida en Microsoft Dynamics AX 2012. Como podemos imaginar, esta clase se encargará añadir filtros dentro de la sentencia having de una select estándar.

Hasta ahora no teníamos forma de realizar este tipo de filtros, ni por sentencias SQL de X++, ni con el objeto Query creado desde el AOT, por lo que si nos encontramos ante la necesidad de utilizarlo se deberá recurrir a la creación de queries mediante este framework.

Imaginemos que necesitamos obtener un listado de los clientes que tienen más de 5 pedidos de venta en el sistema.

La select que deberíamos realizar sería algo así:

En versiones anteriores, hubiésemos sido capaces de obtener un listado de clientes y el número de pedidos de venta de cada cliente realizando un count sobre el RecId de la tabla y un group by por la cuenta del cliente, pero no hubiésemos podido filtrar por este count.

En AX 2012, gracias a esta nueva clase, podemos obtener este mismo resultado por medio del Query Framework, y para conseguirlo tendríamos que hacer la siguiente consulta:

De este modo conseguimos filtrar por el valor que obtenemos de realizar el count(RecId).

QUERYFILTER

La clase QueryFilter, es la segunda novedad de la que vamos a hablar dentro del Query Framework en Dynamics AX 2012. Esta clase nos da la posibilidad de obtener resultados de una unión externa de tablas diferente a lo que podemos obtener mediante sentencias SQL de X++.

La clase QueryFilter se encarga de añadir filtros la cláusula where de una select estándar que utiliza el outer join entre dos tablas. La diferencia que tiene utilizar esta clase con respecto a utilizar la ya conocida QueryBuilRange es que esta segunda añade el filtro dentro de la palabra reservada on de la cláusula join. Por lo que, por medio del QueryFilter, seremos capaces de aplicar filtros una vez que ya se ha realizado el join con sus filtros.

La mejor forma de entender este concepto y la diferencia con el QueryBuilRange es por medio de ejemplos, así que vamos a ello:

Tenemos una consulta que nos da la tabla de Clientes (CustTable) y la tabla de Transacciones (CustTrans), que tienen una relación por la cuenta de cliente (CustAccount).

Esta consulta nos devolverá un listado de todos los clientes, y para aquellos que tengan transacciones, también saldrán todas las transacciones. Por ser un outer join, como decimos, obtendremos todos los clientes, tengan o no transacciones.

Imaginemos ahora, que queremos obtener todos los clientes junto con las transacciones que hayan sido aprobadas únicamente, pero igual que antes, queremos seguir recibiendo aquellos clientes que bien no tienen transacciones o bien estas transacciones todavía no han sido aprobadas. Necesitaríamos generar una select como esta:

Esta es la select que obtenemos al incluir el filtro dentro de un QueryBuildRange. Si en lugar de utilizar el QueryBuilRange optásemos por el QueryFilter, la select obtenida sería la siguiente:

Y el resultado de ejecutar esta select sería distinto, ya que el where, se encarga de aplicar los filtros una vez que el outer join ha sido ejecutado con los filtros pertinentes, por lo que, una vez que tengamos el resultset que resulta de realizar la primera parte de la select, es cuando se aplica el filtro de la cláusula where, por lo que finalmente nos quedaríamos únicamente con aquellos clientes que tienen alguna transacción aprobada, y desecharíamos el resto de clientes.

Aquí tenemos un job en el que podemos ver claramente la diferencia entre el resultado obtenido al utilizar un QueryBuildRange o un QueryFilter, simplemente con ejecutarlo comentando una u otra línea podremos verlo.

 


Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Time limit is exhausted. Please reload CAPTCHA.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información. ACEPTAR

Aviso de cookies