Descubre la nueva Dynamics AX 2012 R3 Entity Store

En prácticamente todas las instalaciones de Microsoft Dynamics AX, en cualquiera de sus versiones, nos vemos en la necesidad de exponer ciertos datos de la aplicación para que otros sistemas puedan utilizarlos. Casi siempre, aunque no únicamente, herramientas de reporting y Business Intelligence. Para conseguirlo diseñamos datawarehouses más o menos completos y procesos ETL para transformar la base de datos transaccional y normalizada de Microsoft Dynamics AX en una fuente de datos más apropiada para la lectura eficiente de la información.

Entity Store - Exposing entities

Para evitarnos esta tarea extra y permitirnos centrar nuestro tiempo en la solución final, se ha publicado una nueva funcionalidad disponible para Microsoft Dynamics AX 2012 R3 llamada Entity Store, que nos va a permitir exponer las entidades de Microsoft Dynamics AX y utilizar todas las novedades del nuevo Microsoft SQL Server 2016 como los nuevos índices columnares en memoria y herramientas diseñadas para optimizar el reporting y permitir una explotación en “casi” tiempo real (near-real time).

Entity Store - Power BI

Este almacén de entidades es una nueva base de datos independiente de la transaccional por lo que, aparte de permitirnos una optimización y escalado independiente, nos va a permitir funcionar siempre con la nueva versión de SQL sin tener que migrar también el servidor transaccional de AX, facilitando la adopción de las últimas novedades. Actualmente es compatible con SQL Server 2014 y 2016 así como Azure SQL.

La herramienta se integra y configura en la aplicación (actualmente como un hotfix independiente, pero formará parte del próximo parche acumulativo para AX 2012 R3) y utiliza el Data Import/Export Framework (DIEF) para coordinar la actualización de las entidades, que pueden configurarse a cierta frecuencia de forma independiente.

Esta es una primera versión para introducir la funcionalidad y proveer las bases de su funcionamiento, pero Microsoft ya ha anunciado que están invirtiendo en este Data Entity por lo que podemos esperar novedades en el futuro, ya que esta promete ser la puerta de integración de nuestros sistemas con el resto de tecnologías de Microsoft referentes al reporting y business intelligence, que están avanzando mucho de la mano de Azure y SQL Server.

Por ejemplo, Microsoft ya nos sugiere que estas entidades están preparadas para trabajar con Azure Machine Learning, Power BI, Azure Data Factory y herramientas clásicas de BI (como data warehouse clásico, data lake para AX, …) y Big Data (Hadoop). Todas estas herramientas que ya están disponibles en Azure (Azure SQL, SQL-DW, Azure Data Factory, HDInsight, Azure Data Lake, Azure Data Lake Analysis Services, y Machine Learning) son parte también del Cortana Intelligence Suite (CIS), por lo que este nuevo almacén de datos consolidado es sólo el principio 😉

Toda la información disponible en el siguiente white paper de Microsoft:

El parche se puede descargar desde LCS buscando “Entity store” o KB3147499.

* Las imágenes de este post están extraídas del blog Dynamics AX Business Intelligence!!

Fixing DB synchronization problems in Microsoft Dynamics AX 2012 [EN]

Sometimes when synchronizing the database in Microsoft Dynamics AX 2012 we get some nonsense error messages. In my example, I’m getting an error stating that it can’t change the data type in a table field. But this field doesn’t exists on this table, same error says that is trying to convert a data field into a field of another table… weird.

ndb-sync-001

This is an indicator that we are facing an ID problem with the table and/or the table fields. Unfortunately, we don’t have the proper tools to diagnose and fix this kind of problems, so we need to use dirty tricks like fixing the conflict directly in the database.

Of course, what I’m describing here is not recommended at all and it comes with a huge risk of loosing data and giving more problems that the ones is trying to fix if you don’t do it with care. Always test this in a dedicated test system and, if possible, try to avoid it.

Continue Reading…

Problemas de sincronización en Microsoft Dynamics AX 2012

A veces al sincronizar la base de datos de Microsoft Dynamics AX 2012 obtenemos errores sin sentido. En mi ejemplo, estoy recibiendo un error indicando que no se puede cambiar el tipo de dato de un campo en una tabla. Pero ese campo ni siquiera existe en esa tabla, el mismo mensaje de error indica que intenta convertir un campo de una tabla en otro campo de otra tabla… absurdo.

ndb-sync-001

Este es un signo claro de que un conflicto de IDs en la tabla o en los campos está ocurriendo. Desafortunadamente no tenemos herramientas apropiada en AX para gestionar estos conflictos, así que voy a recurrir directamente a la base de datos.

Me encanta el olor a UPDATE SQLDICTIONARY por las mañanas

Por supuesto, todo lo que voy a contar no está para nada recomendado y conlleva un grave riesgo de pérdida de datos y de generar más problemas de los que se intenta solucionar con ellos si no se hace con cuidado. Probarlo siempre antes en entorno de test y, si es posible, intenta solucionarlo de otra forma.

Continue Reading…

Consultar roles de seguridad desde SQL en AX 2012

No es algo común pero en algún caso nos puede venir bien consultar qué roles de seguridad tiene un usuario consultando la base de datos. Lo ideal sería utilizar servicios web o algo parecido, utilizando un código X++ parecido al siguiente (código extraído del capítulo 10: “Licencia, Configuración y Seguridad” de mi libro):

static void QueryRoles(Args _args)
{
    SecurityRole            securityRole;
    SecurityUserRole        securityUserRole;

    while select securityUserRole
            where securityUserRole.User == 'admin'
        join securityRole
            where securityRole.RecId == securityUserRole.SecurityRole
    {
        info(strFmt("%1", SysLabel::labelId2String(securityRole.Name)));
    }
}

Si insistimos en hacer esta consulta desde SQL Server nos vamos a llevar una sorpresa. La tabla SecurityUserRole que almacena los roles asignados a cada usuario existe en la base de datos transaccional de AX, pero la tabla SecurityRole, que almacena los roles en si, no existe. Sería lógico pensar que, a lo mejor, la tabla existe en la base de datos modelo (_model), pero tampoco la encontramos ahí.

Tras recurrir al truco que comentaba unos cuantos post atrás, nos encontramos con que la tabla está efectivamente en la base de datos modelo, pero abstraída tras un procedimiento almacenado, y tiene esta pinta:

SELECT T1.NAME, T1.ALLOWPASTRECORDS, ...
FROM [XXXX_model].[dbo].SECURITYROLE_INLINEFUNC(N'en_us') T1

Por tanto, jugando un poco con la consulta, podemos obtener el mismo resultado que consultando desde X++:

SecurityUserRole X++

Pero desde SQL Server, y por tanto desde cualquier aplicación externa:

SecurityUserRole SQL

Utilizar con cuidado 😉

 

Error: Concurrent number of AOS for this application exceeds the licensed number

Otro error recurrente al mover o copiar entornos o bases de datos es referente al número máximo de AOS que podemos ejecutar en una misma instalación por cuestiones de licencia. Esto ocurre en diferentes versiones y revisiones pero en mi caso me lo estoy encontrando sobre todo en AX 2012:

Object Server 01:  Concurrent number of AOS' for this application exceeds the licensed number AX 2012

Para solucionarlo, podemos ejecutar esta sentencia en la base de datos que hemos copiado:

UPDATE dbo.SysServerSessions SET Status = 0 WHERE Status = 1;

Esto liberará las sesiones que hayan quedado almacenadas en la base de datos antes de copiarla, permitiendo conectarle un AOS diferente, lo que es totalmente válido para una licencia normal y bastante típico al copiar bases de datos de producción para refrescar entornos de pruebas o desarrollo.

NOTA: Ejecutar sentencias SQL directamente sobre la base de datos siempre supone un riesgo. Ejecutar con precaución y en entornos de testeo.

En busca de la tabla perdida… herencia de tablas en AX 2012

Si alguien ha creado o mantiene un desarrollo que acceda directamente a la base de datos de Microsoft Dynamics AX 2012 (por ejemplo, algún sistema externo de Business Intelligence), se habrá encontrado con el fenómeno de la “tabla fantasma“. Hay muchos casos, pero analicemos por ejemplo la tabla OMOperationUnit. Esta tabla existe en el AOT, podemos explorarla desde Dynamics AX y ver los datos que contiene, por lo que esos datos deben estar almacenados en alguna parte. Sin embargo la tabla no existe en la base de datos SQL Server subyacente. Entonces, ¿Dónde están los datos?

En primer lugar hay que fijarse que este fenómeno sucede siempre en tablas heredadas o que soportan herencia, por ejemplo:

Tablas heredadas en Microsoft Dynamics AX 2012

Como la tabla existe y almacena datos en el AOT, es obvio que la tabla debe existir en la base de datos. Una buena herramienta de la que disponemos en X++ es la función getSQLStatement que podemos usar en variables de tipo buffer o en consultas, de esta forma:

static void Job43(Args _args)
{
    OMOperatingUnit tabla;

    select generateOnly tabla;

    info(tabla.getSQLStatement());
}

Esta función nos devuelve el SQL que se enviará a la base de datos para obtener los datos que se requieren desde X++. Aquí tenemos la explicación al problema de la tabla fantasma:

Consulta SQL de tablas heredadas en Microsoft Dynamics AX 2012

Si analizamos bien el SQL obtenido, incluso si lo probamos directamente contra la base de datos SQL Server, descubrimos la estructura interna que el AOT ha desarrollado en la base de datos para almacenar los datos de las tablas heredadas:

Consulta SQL de tablas heredadas en Microsoft Dynamics AX 2012

En este caso, la tabla heredada obtiene los datos de tablas totalmente diferentes mediante algunos filtros. Dependiendo del tipo de tabla heredada, las tablas físicas pueden tener otra forma, pero en cualquier caso de esta forma obtenemos una consulta válida que podemos utilizar para acceder a los datos desde un sistema externo, o podemos crear una vista con esa consulta para simular la existencia de la tabla, si fuera necesario.