Variables de indicador en aplicaciones SQLJ

En programas SQLJ, las variables de indicador se pueden utilizar para pasar el valor NULL a un servidor de datos o de un servidor de datos, pasar el valor por omisión de una columna al servidor de datos o indicar que un valor de la variable del lenguaje principal no está asignado.

Una variable o expresión de lenguaje principal puede ir seguida de una variable de indicador. Una variable de indicador empieza por un signo de dos puntos (:) y tiene un tipo de datos short. Para la entrada, una variable de indicador indica si la variable o expresión de lenguaje principal correspondiente tiene el valor por omisión, un valor que no sea nulo, el valor nulo o bien no está asignado. Una variable no asignada en una sentencia de SQL tiene el mismo resultado que si la variable y su columna de destino no aparecieran en la sentencia de SQL. Para la salida, una variable de indicador indica dónde tiene un valor no nulo o un valor nulo la variable o expresión de lenguaje principal correspondiente.

En los programas SQLJ, las variables indicadoras que indican un valor nulo realizan la misma función que asignar el valor nulo de Java a una columna de la tabla. Sin embargo, es necesario utilizar una variable de indicador para recuperar el valor nulo de SQL de una tabla a una variable de lenguaje principal.

Las variables de indicador se pueden usar para asignar el valor DEFAULT o el valor UNASSIGNED a columnas con el fin de simplificar la codificación en las aplicaciones. Por ejemplo, si una tabla tiene cuatro columnas y necesita actualizar cualquier combinación de estas columnas, sin el uso de variables de indicador por omisión o variables de indicador no asignadas, necesitará 15 sentencias UPDATE para llevar a cabo todas las combinaciones de actualizaciones. Con variables de indicador por omisión y variables de indicador no asignadas, se puede utilizar una sentencia UPDATE con las cuatro columnas en la sentencia SET para llevar a cabo todas las actualizaciones posibles. Las variables de indicador se utilizan para indicar qué columnas desea establecer en los valores por omisión y qué columnas no desea actualizar.

Para la entrada, SQLJ ofrece soporte al uso de variables de indicador para sentencias INSERT, UPDATE o MERGE.

Si personaliza la aplicación SQLJ, puede asignar uno de los valores siguientes a una variable de indicador en una aplicación SQLJ para especificar el tipo de la variable de lenguaje principal de entrada correspondiente.

Valor de indicador Constante equivalente Significado del valor
-1 sqlj.runtime.ExecutionContext.DBNull Nulo
-2, -3, -4, -6   Nulo
-5 sqlj.runtime.ExecutionContext.DBDefault Valor por omisión
-7 sqlj.runtime.ExecutionContext.DBUnassigned Sin asignar
valor-corto >=0 sqlj.runtime.ExecutionContext.DBNonNull No nulo

Si no personaliza la aplicación, puede asignar uno de los valores siguientes a una variable de indicador para especificar el tipo de la variable de lenguaje principal de entrada correspondiente.

Valor de indicador Constante equivalente Significado del valor
-1 sqlj.runtime.ExecutionContext.DBNull Nulo
-7 <= valor-corto < -1   Nulo
0 sqlj.runtime.ExecutionContext.DBNonNull No nulo
valor-corto >0   No nulo

Para la salida, SQLJ ofrece soporte al uso de variables de indicador para las sentencias siguientes:

  • Parámetros CALL con OUT o INOUT
  • FETCH iterador INTO variable-lenguajeprincipal
  • SELECCIONAR. INTO host-variable-1,…host-variable-n

SQLJ asigna uno de los valores siguientes a una variable de indicador para especificar si se ha recuperado un valor nulo de SQL en la variable de lenguaje principal correspondiente.

Valor de indicador Constante equivalente Significado del valor
-1 sqlj.runtime.ExecutionContext.DBNull El valor recuperado es SQL NULL
0   El valor recuperado no es SQL NULL

Las variables de indicador no se pueden utilizar para actualizar los conjuntos de resultados. Para asignar valores nulos o valores por omisión a conjuntos de resultados o para indicar que las columnas no están asignadas, invoque ResultSet.updateObject en los objetos ResultSet subyacentes de JDBC de los iteradores de SQLJ.

Los ejemplos siguientes muestran cómo utilizar variables de indicador.

Todos los ejemplos requieren que el servidor de datos admita los indicadores ampliados.

Ejemplo de uso de indicadores para asignar el valor por omisión a columnas durante una operación INSERT:

En este ejemplo, las columnas MGRNO y LOCATION deben establecerse en los valores por omisión. Para ello, el código efectúa estos pasos:
  1. Asigna el valor ExecutionContext.DBNonNull a las variables de indicador (deptInd, dNameInd, rptDeptInd) para las variables de lenguaje de principal de entrada (dept, dName, rptDept) que envían valores que no son por omisión a las columnas de destino.
  2. Asigna el valor ExecutionContext.DBDefault a las variables de indicador (mgrInd, locnInd) para las variables de lenguaje principal de entrada (mgr, locn) que envían valores por omisión a las columnas de destino.
  3. Ejecuta una sentencia INSERT con los pares de variable de lenguaje principal y variable de indicador como entrada.

Los números que aparecen a la derecha de algunas sentencias corresponden a los pasos descritos anteriormente.

import sqlj.runtime.*;
…
String dept = "F01";
String dName = "SHIPPING";
String rptDept = "A00";
String mgr, locn = null;
short deptInd, dNameInd, mgrInd, rptDeptInd, locnInd;
// Set indicator variables for dept, dName, rptDept to non-null
deptInd = dNameInd = rptDeptInd = ExecutionContext.DBNonNull;    1 
mgrInd = ExecutionContext.DBDefault;                             2 
locnInd = ExecutionContext.DBDefault;
#sql [ctxt]                                                      3 
  {INSERT INTO DEPARTMENT
    (DEPTNO, DEPTNAME, MGRNO, ADMRDEPT, LOCATION)
    VALUES (:dept :deptInd, :dName :dNameInd,:mgr :mgrInd,
    :rptDept :rptDeptInd, :locn :locnInd)};

Ejemplo de uso de indicadores para asignar el valor por omisión para que deje los valores de columna sin asignar durante una operación UPDATE:

En este ejemplo, en las filas para el departamento F01, la columna MGRNO debe establecerse en su valor por omisión, el valor de la columna DEPTNAME debe cambiarse a RECEIVING y las columnas DEPTNO, DEPTNAME, ADMRDEPT y LOCATION deben mantenerse sin modificar. Para ello, el código efectúa estos pasos:
  1. Asigna el valor nuevo de la columna DEPTNAME a la variable de lenguaje principal de entrada dName.
  2. Asigna el valor ExecutionContext.DBDefault a la variable de indicador (mgrInd) para la variable de lenguaje principal de entrada (mgr) que envía el valor por omisión a la columna de destino.
  3. Asigna el valor ExecutionContext.DBUnassigned a las variables de indicador (deptInd, dNameInd, rptDeptInd y locnInd) para las variables de lenguaje principal de entrada (dept, dName, rptDept y locn) que la operación UPDATE debe mantener sin modificar.
  4. Ejecuta una sentencia UPDATE con los pares de variable de lenguaje principal y variable de indicador como entrada.

Los números que aparecen a la derecha de algunas sentencias corresponden a los pasos descritos anteriormente.

import sqlj.runtime.*;
…
String dept = null;
String dName = "RECEIVING";                                      1 
String rptDept = null;
String mgr, locn = null;
short deptInd, dNameInd, mgrInd, rptDeptInd, locnInd;
dNameInd = ExecutionContext.DBNonNull;
mgrInd = ExecutionContext.DBDefault;                             2 
deptInd = rptDeptInd = locnInd = ExecutionContext.DBUnassigned;  3 
#sql [ctxt]                                                      4 
  {UPDATE DEPARTMENT
    SET DEPTNO = :dept :deptInd,
        DEPTNAME = :dName :dNameInd,
        MGRNO = :mgr :mgrInd,
        ADMRDEPT = :rptDept :rptDeptInd,
        LOCATION = :locn :locnInd
    WHERE DEPTNO = "F01"
  };

Ejemplo de uso de indicadores para recuperar valores NULL de columnas:

En este ejemplo, la columna HIREDATE puede devolver el valor NULL. Para ello, el código efectúa estos pasos:
  1. Define una variable de indicador para indicar cuándo se devuelve el valor NULL de HIREDATE.
  2. Ejecuta sentencias FETCH con los pares de variable de lenguaje principal y variable de indicador como salida.
  3. Comprueba la variable de indicador para determinar si se devuelve un valor NULL.

Los números que aparecen a la derecha de algunas sentencias corresponden a los pasos descritos anteriormente.

import sqlj.runtime.*;
…
#sql iterator ByPos(String, Date);  // Declare positioned iterator ByPos
{
  …
  ByPos positer;                    // Declare object of ByPos class
  String name = null;               // Declare host variables
  Date hrdate = null;
  short indhrdate = null;           // Declare indicator variable       1 
  #sql [ctxt] positer = 
    {SELECT LASTNAME, HIREDATE FROM EMPLOYEE};                         
                                    // Assign the result table of the SELECT
                                    // to iterator object positer
  #sql {FETCH :positer INTO :name, :hrdate :indhrdate };                2 
                                    // Retrieve the first row
  while (!positer.endFetch())       // Check whether the FETCH returned a row
  { if(indhrdate == ExecutionContext.DBNonNull {                        3 
     System.out.println(name + " was hired in " +
      hrdate); }
    else {
     System.out.println(name + " has no hire date "); }
    #sql {FETCH :positer INTO :name, :hrdate };
                                    // Fetch the next row
  }
  positer.close();                  // Close the iterator               5 
}

Ejemplo de asignación de valores por omisión a columnas de conjuntos de resultados:

En este ejemplo, la columna HIREDATE de un conjunto de resultados debe establecerse en el valor por omisión. Para ello, el código efectúa estos pasos:
  1. Recupera el ResultSet subyacente del iterador que mantiene los datos recuperados.
  2. Ejecuta el método ResultSet.updateObject con la constante DB2PreparedStatement.DB_PARAMETER_DEFAULT para asignar el valor por omisión a la columna de conjunto de resultados.

Los números que aparecen a la derecha de algunas sentencias corresponden a los pasos descritos anteriormente.

#sql public iterator sensitiveUpdateIter 
 implements sqlj.runtime.Scrollable, sqlj.runtime.ForUpdate 
 with (sensitivity=sqlj.runtime.ResultSetIterator.SENSITIVE, 
 updateColumns="LASTNAME, HIREDATE") (String, Date);

  String name;                    // Declare host variables
  Date hrdate;

sensitiveUpdateIter iter = null;
#sql [ctx] iter = { SELECT LASTNAME, HIREDATE FROM EMPLOYEE};

iter.next();

java.sql.ResultSet rs =  iter.getResultSet();                       1 
rs.updateString("LASTNAME", "FORREST");
rs.updateObject
 (2, com.ibm.db2.jcc.DB2PreparedStatement.DB_PARAMETER_DEFAULT););  2,3 
rs.updateRow();
iter.close();