
Cuando tenemos programas que se conectan por JDBC u ODBC y al mirar con WRKACTJOB en los trabajos QZDASOINIT nos comenzamos a rascar la cabeza tratando de adivinar que está ocurriendo.
Si nuestra aplicaciones son Cliente/Servidor y cada usuario se conecta con un perfil diferente al menos podemos distinguir a quien corresponde cada conexión con el CURRENT USER y podemos obtener su dirección IP revisando dentro del trabajo.
Cuando tenemos aplicaciones web, por lo general todos se conectan usando un mismo perfil de usuario y una misma dirección IP , lo cual se puede volver desconcertante. Los usuarios suelen estar declarados en tablas de la base de datos o en un directorio activo o LDAP, lo cual no es fácil de filtrar y detectar.
Ni hablemos de saber que está ocurriendo en ese momento en que queremos ver su SQL, porque en ninguno de los dos casos podremos verlo a menos que activemos el DBMON o un supervisor de SQL para luego analizarlo.
No sería fantástico poder ver las instrucciones SQL de la misma forma que usamos el WRKACTJOB?
Prueben esto:
WITH ACTIVE_USER_JOBS (Q_JOB_NAME, CPU_TIME, RUN_PRIORITY)
AS (SELECT JOB_NAME, CPU_TIME, RUN_PRIORITY
FROM TABLE (QSYS2.ACTIVE_JOB_INFO('NO','','','')) x
WHERE JOB_TYPE <> 'SYS' )
SELECT Q_JOB_NAME,
CPU_TIME,
RUN_PRIORITY,
CURRENT TIMESTAMP - V_SQL_STMT_START_TIMESTAMP AS SQL_STMT_DURATION,
B.*
FROM ACTIVE_USER_JOBS, TABLE(QSYS2.GET_JOB_INFO(Q_JOB_NAME)) B
WHERE V_SQL_STMT_STATUS = 'ACTIVE'
ORDER BY SQL_STMT_DURATION DESC
Esto les mostrará los comandos SQL de los trabajos activos.
En pocas palabras, estamos usando una serie de UDTFs nuevos que corresponden a V7R2 y que proveen servicios similares al WRKACTJOB, pero con mayor nivel de detalle.
Ahora bien, entre todos los valores que podemos recuperar hay unos registros especiales y EDITABLES!!! Esto significa que de forma programática podríamos guardar valores desde nuestro programa como si fueran variables y consultarlos.
V_CLIENT_WRKSTNNAME CHAR(255) Value of the SQL CLIENT_WRKSTNNAME special register.
V_CLIENT_APPLNAME CHAR(255) Value of the SQL CLIENT_APPLNAME special register.
V_CLIENT_ACCTNG CHAR(255) Value of the SQL CLIENT_ACCTNG special register.
V_CLIENT_PROGRAMID CHAR(255) Value of the SQL CLIENT_PROGRAMID special register.
V_CLIENT_USERID CHAR(255) Value of the SQL CLIENT_USERID special register.
Qué podríamos guardar?
IP del usuario final, Nombre de la aplicación, Nombre del programa que ejecuta, Usuario local al sistema y cualquier otro valor que nos permita identificar la sesion.
Para poder actualizar esos valores deberemos comandos como este, o jugar con las propiedades de la conexión. Me quedo con el stored procedure:
CALL SYSPROC.WLM_SET_CLIENT_INFO('MyUser', 'https://www.linkedin.com/redir/invalid-link-page?url=192%2e168%2e123%2e123',
'CORE Banking', 'Modulo1', 'ProgramaXYZ02')
Y eso permitirá combinar la información de SQL, el programa asociado, la IP del cliente y su nombre de usuario.
Es un poco lo que usamos con WEBACTJOB, aunque con algunos agregados para poder terminar el trabajo, ver su joblog ,etc.
En un próximo artículo les explicaré como podemos tomar una "foto" de todos los trabajos corriendo con sus conexiones y comandos SQL para poder analizar que ocurre, sin tener que ejecutar el DBMON.
Suerte