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.

Microsoft Dynamics AX 2012 R3 CU8 Demo VM V1

Microsoft Dynamics AX 2012 R3

Ya se ha publicado la máquina virtual demo de la también recién publicada Microsoft Dynamics AX 2012 R3 CU8. Esta máquina virtual viene, como de costumbre, actualizada con las últimas versiones de todo el software y con datos de prueba de las nuevas funcionalidades:

Se puede descargar de PartnerSource y CustomerSource:

Recordar la posibilidad que tenemos desde la revisión R3 de desplegar estas máquinas virtuales directamente en Azure desde , como ya comenté hace un tiempo 🙂

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.