El misterio de la query que no filtra

En realidad no tiene nada de misterio, más bien un error de concepto.

Recientemente un compañero se ha encontrado con un problema al querer usar una query creada en el AOT para alimentar un vista y usando un filtro en la query con la clase SysQueryRangeUtil y descubrimos una curiosidad.

Creando el problema

La query era bastante simple y solo mostraba transacciones de contabilidad a partir de las tablas GeneralJournalEntry y GeneralJournalAccountEntry. Además filtrando los datos según la empresa activa con un rango en la propia query, en el campo Ledger de la primera tabla como se ve en la imagen:

Query en Visual Studio

Extendiendo la clase SysQueryRangeUtil creó un nuevo método para filtrar a partir del método Ledger::current() y se aplicó el rango a la query como vemos arriba:

Extensión en visual studio

A partir de aquí usamos la query para alimentar una vista y añadimos dos campos a la vista para testear:

Vista en Visual Studio

Hasta aquí todo normal. Vamos a abrirla en el explorador de tablas…

Explorador de tablas

No hay datos, y os puedo asegurar que en las tablas los hay:

Registros en SSMS

Qué está pasando aquí? Si usamos la query en un job (sí, sí, Runnable Class…) el filtrado funciona y devuelve datos.

Psyduck is confused
Yo en homenaje a “Psyduck is confused” de cazapelusas.com

Vamos a ver la vista en SQL:

Diseño de la vista en SSMS

Vaya, parece que sí se está filtrando alguna cosa, el rango de la query funciona! Si? Seguro? A qué empresa corresponde ese RecId de la tabla Ledger?

Registro de DAT

Qué haces besando a la lisiada!?
Qué haces consultando a la maldita DAT!?

Qué pasa?

La explicación es muy sencilla, pero no te lo planteas si no te encuentras un caso así. Mientras que la vista* es un objeto del Data Dictionary y cuando sincronizamos se crea en SQL Server la query* es un objeto de X++ y solo existe en la aplicación. La vista se sincroniza en SQL Server, podemos verla en SSMS y lanzar consultas contra ella. La query del AOT no existe en SQL Server. Alimenta a la vista, pero no se aplican los rangos dinámicos de la SysQueryRangeUtils porque al final, tanto la query como el filtro dinámico, son código X++ puro.

La solución pasa por quitar el rango en la query y añadirlo en el código del formulario por ejemplo. Con esto tendríamos la query filtrada

(*) Nota: los links son a la documentación de AX 2012 porque para 365 no hay developer reference como teníamos antes.

Deja un comentario

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

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