XSQL-SCRIPT automáticamente no prepara statements no preparables

Cache

XSQL-SCRIPT automáticamente no prepara statements no preparables

En los programas XSQL-SCRIPTS las sentencias ejecutadas contra la base de datos son por defecto prepared a menos que el programador índique lo contrario de forma explícita mediante el atributo prepare=’false’.

A partir de octubre de 2013 los statements ejecutados desde XSQL-SCRIPTS que contengan elementos que provoquen que no puedan ser prepared, automáticamente no serán preparados.

Este cambio se ha realizado para evitar un consumo de memoria innecesario en la caché de la sesión de base de datos que utiliza cursores que son variables, ya que no son reutilizables.
El siguiente ejemplo muestra un SELECT que no tiene sentido guardar en la caché de statements de la sesión de base de datos, porque debido al uso de NVL, las variables deben ser parseadas sin que puedan ser seteadas desde el prepared.

<select prefix='m_'>
  <columns>estado, fecbaj</columns>
  <from table='gartclie' />
  <where>
    codcli = <p_tercer /> AND
    codart = <p_codart /> AND
    (<nvl>udmven, <whitespace /></nvl> = <nvl><p_udmven />, <whitespace /></nvl> OR udmven IS NULL)
  </where>
  <order>varlog DESC, udmven DESC</order>
</select>

En este caso, el select sería preparable realizando la sustitución de las variables en el tag NVL.
Si la sentencia se prepara, transformada a Informix sería

SELECT estado, fecbaj
  FROM gartclie
 WHERE codcli = ? AND
       codart = ? AND
       (NVL(udmven, '') = NVL('KG', '') OR udmven IS NULL)
ORDER BY varlog DESC, udmven DESC

donde los valores de “p_udmven” deben ser parseados, no pueden ser preparados. Si el statement se prepara tal cual, se guarda en la caché de la sesión de informix. Para valores diferentes de “p_udmven”, se estarían cacheando statements variables que no son reutilizables, con el consiguiente consumo innecesario de memoria.

Es por éste motivo que el sistema automáticamente no prepara este tipo de sentencias para evitar que sean cacheadas en la sesión de base de datos.

Mediante el comando de informix

onstat -g stm ses_id

se puede observar los cursores abiertos de una sesión y durante la ejecución del script se mostrarían los cursores activos.
Y con el comando

onstat -g ses ses_id

se muestra toda la información de memoria relativa a la sesión.

A continuación se expone un ejemplo completo.

<xsql-script name='test_memory'>
   <body>
      <foreach>
         <select prefix='p_'>
            <columns>
               gvenpedl.udmven, garticul.udmbas, gvenpedl.codart, gvenpedl.varlog,
               gvenpedh.empcode, gvenpedh.fecha, gvenpedh.cambio, gvenpedh.tercer,
               gvenpedh.delega, gvenpedh.depart
            </columns>
            <from table = 'gvenpedh'>
               <join table = 'gvenpedl' type = 'inner'>
                  <on>gvenpedh.cabid = gvenpedl.cabid</on>
                  <join table = 'garticul' type = 'inner'>
                     <on>gvenpedl.codart = garticul.codigo</on>
                  </join>
               </join>
            </from>
         </select>
         <do>
           <set name='m_varlog' type='string'><ifnull><p_varlog /><string /></ifnull></set>
            <foreach>
                <select prepare-cache='true' prefix='x_'>
                    <columns>estado, fecbaj</columns>
                    <from table='gartclie' />
                    <where>
                        codcli = '#p_tercer' AND
                        codart = <p_codart /> AND
                        (<nvl>udmven, <whitespace /></nvl> = <nvl><p_udmven />, <whitespace /></nvl> OR udmven IS NULL) AND
                        (<nvl>varlog, <whitespace /></nvl> = <nvl><p_varlog />, <whitespace /></nvl> OR varlog IS NULL)
                    </where>
                    <order>varlog DESC, udmven DESC</order>
                </select>
                <do>
                    <foreach.exit/>
                </do>
            </foreach>
         </do>
      </foreach>
   </body>
</xsql-script>

El sistema emitirá el siguiente mensaje para indicar que el segundo SELECT no irá prepared ya que contiene elementos variables que hacen que no sea reutilizable y evitar así uso innecesario de memoria de la sesión de base de datos:
disabled prepare-cache cause statement contains variables as strings or NVL