get

La sentencia EGL get recupera un solo registro de archivo o fila de base de datos y proporciona una opción que permite sustituir o suprimir los datos almacenados más tarde en el código. Además, esta sentencia permite recuperar un conjunto de filas de base de datos y sustituir cada fila sucesiva en el siguiente registro SQL de una matriz dinámica.

La sentencia get se identifica a veces como get by key value y es distinta de otras sentencias que empiezan por la palabra get.


Diagrama de sintaxis de la sentencia get
nombre de registro
Nombre del objeto de E/S que debe leerse; un DLISegment, un registro indexado, MQ, relativo, serie o SQL. Para el proceso SQL, el nombre de registro es obligatorio si no se especifica la cláusula EGL INTO (descrita más adelante).
forUpdate
Opción que permite utilizar una sentencia EGL posterior para sustituir o suprimir los datos recuperados del archivo o base de datos.

Si el recurso es recuperable (como en el caso de un archivo VSAM o una base de datos SQL o DL/I), la opción forUpdate bloquea el registro de forma que otros programas no puedan cambiarlo hasta que se produzca un compromiso. Encontrará los detalles sobre el proceso de compromiso en Unidad lógica de trabajo.

usingPCB nombrePCB
Opción que permite especificar el nombre de un PCB, según lo definido en el registro PSB, para utilizarlo en lugar del PCB por omisión.
with #dli{ sentencia DLI }
Opción que permite una sentencia explícita DL/I GU o GHU, como se describe en la sección dedicada a la directiva #dli. No deje espacios entre #dli y el corchete de apertura.
IDconjuntoResultados
Un identificador de conjunto de resultados que se utiliza en una sentencia EGL replace, delete o execute, así como en una sentencia EGL close. Para obtener detalles, consulte el apartado resultSetID.
singleRow
Opción que provoca la generación de código SQL más eficiente, que es adecuada si está seguro de que el criterio de búsqueda de la sentencia get se aplica sólo a una fila y si no tiene intención de actualizar o suprimir la fila. Si especifica esta opción cuando el criterio de búsqueda se aplica a varias filas, se produce un error de E/S en tiempo de ejecución. Para obtener más detalles, consulte el apartado Registro SQL.
#sql{ sentenciaSQL }
Opción que permite una sentencia SQL SELECT explícita, como se describe en el apartado Soporte SQL. No deje espacios entre #sql y el corchete de apertura.
into ... elemento
Una cláusula INTO que identifica las variables de lenguaje principal EGL que reciben valores desde una base de datos relacional. Esta cláusula es obligatoria al procesar SQL en cualquiera de estos casos:
  • No se ha especificado un registro SQL; o
  • Se especifican tanto un registro SQL como una sentencia SQL SELECT explícita, pero no hay una columna en la cláusula SQL SELECT asociada con un elemento de registro. (La asociación se encuentra en el componente de registro SQL, como se indica en el apartado Propiedades de elementos SQL).

En una cláusula como esta (que está fuera de un bloque #sql{ }), no incluya un punto y coma antes del nombre de una variable de lenguaje principal.

IDsentenciaPreparada
El identificador de una sentencia EGL prepare que prepara una sentencia SQL SELECT durante la ejecución. La sentencia get ejecuta la sentencia SQL SELECT dinámicamente. Para obtener detalles, consulte el apartado prepare.
using ... elemento
Una cláusula USING que identifica las variables de lenguaje principal EGL que quedan a disposición de la sentencia SQL SELECT preparada durante la ejecución. En una cláusula como esta (que está fuera de un bloque sql-and-end), no incluya un punto y coma antes del nombre de la variable de lenguaje principal.
usingKeys ... elemento
Identifica una lista de elementos de clave utilizados para construir el componente de clave-valor de la cláusula WHERE en la sentencia SQL implícita. La sentencia SQL implícita se utiliza durante la ejecución si no especifica una sentencia SQL explícita.

Si no especifica una cláusula usingKeys, el componente de clave-valor de la sentencia implícita se basa en el componente de registro SQL al que se hace referencia en la sentencia get o es la base de la matriz dinámica a la que se hace referencia en la sentencia get.

En el caso de una matriz dinámica, los elementos de la cláusula usingKeys (o las variables de lenguaje principal del registro SQL) no deben estar en el registro SQL que es la base de la matriz dinámica.

La información de usingKeys se pasa por alto si especifica una sentencia SQL explícita.

matriz dinámica SQL
El nombre de una matriz dinámica compuesta de registros SQL.
El ejemplo siguiente muestra cómo leer y sustituir un registro de archivo:
  emp.empnum = 1;         // establece la clave en el registro emp

  try
    get emp forUpdate;
  onException
    myErrorHandler(8);  // sale del programa
  end

  emp.empname = emp.empname + " Smith";

  try
    replace emp;
  onException
    myErrorHandler(12);
  end
La siguiente sentencia get utiliza el registro SQL emp al recuperar una fila de la base de datos, sin que sea posible la actualización o supresión subsiguiente:
  try
    get emp singleRow into empname with
      #sql{
        select empname
        from Employee
        where empnum = :empnum
      };
  onException
    myErrorHandler(8);
  end
El ejemplo siguiente utiliza el mismo registro SQL para sustituir una fila SQL:
  try
    get emp forUpdate into empname with
      #sql{
        select empname
        from Employee
        where empnum = :empnum
      };

  onException
    myErrorHandler(8);  // sale del programa
  end

  emp.empname = emp.empname + " Smith";

  try
    replace emp;
  onException
    myErrorHandler(12);
  end

En el entorno CICS para MVS/ESA, la posición get se pierde cuando se emite una operación de compromiso o retrotracción, o a continuación de una sentencia converse si se ejecuta en modalidad segmentada.

Los detalles de la sentencia get dependen del tipo de registro. Para obtener detalles acerca del proceso DL/I, consulte el tema Registro DLISegment. Para obtener detalles acerca del proceso SQL, consulte el tema Registro SQL.

Registro DLISegment

La sentencia get genera una sentencia DL/I GU. La sentencia get...forUpdate genera una sentencia DL/I GHU. Los usos principales de la sentencia get son los siguientes:
  • Para leer un segmento a fin de realizar alguna acción con los datos de ese segmento, como por ejemplo imprimir un informe o una factura.
  • Para retener un segmento (en combinación con la opción forUpdate) a fin de utilizar las palabras clave EGL delete o replace para eliminar o actualizar un segmento. En la mayoría de los casos, no es necesario ejecutar una sentencia get antes de añadir un registro.
Para ver un ejemplo de utilización de la sentencia get...forUpdate con DL/I, consulte la sección correspondiente a la sentencia delete.
DL/I también da soporte al uso de llamadas de vía de acceso en sentencias get. Esto significa que puede leer segmentos padre para todos los niveles de segmento entre el segmento de nivel más bajo que esté leyendo y el segmento raíz. En el ejemplo siguiente, DL/I leerá los tres segmentos (cliente, ubicación y pedido) en sus registros DLISegment respectivos con una sola llamada:
get myCustomer, myLocation, myOrder;
EGL generará el siguiente código pseudo-DL/I a partir de esta sentencia:
GU STSCCST*D (STQCCNO = :myCust.customerNo) 
   STSCLOC (STQCLNO = :myLocation.locationNo) 
   STPCORD

Registro indexado

Si emite una sentencia get en un registro indexado, el valor de clave del registro determina qué registro se recupera del archivo.

Si desea sustituir o suprimir un registro indexado (o relativo), debe emitir una sentencia get para el registro y, a continuación, emitir la sentencia de cambio de archivo (replace o delete) sin que intervenga ninguna operación de E/S en el mismo archivo. Después de emitir la sentencia get, el resultado de la próxima operación de E/S en el mismo archivo será el siguiente:
  • Si la próxima operación de E/S es una sentencia replace en el mismo registro EGL, se cambia el registro del archivo
  • Si la próxima operación de E/S es una sentencia delete en el mismo registro EGL, el registro del archivo se marca para supresión
  • Si la próxima operación de E/S es una sentencia get en un registro del mismo archivo e incluye la opción forUpdate, una sentencia replace o delete subsiguiente es válida en el registro de archivo de lectura recién creado
  • Si la próxima operación de E/S es una sentencia get en el mismo registro EGL (sin la opción forUpdate) o es una sentencia close en el mismo archivo, el registro de archivo se libera sin cambios.

Si el archivo es un archivo VSAM, la sentencia de EGL get (con la opción forUpdate) impide que otros programas cambien el registro. En los programas de proceso por lotes de z/OS, el bloqueo permanece hasta que se produce un compromiso, lo que podría no suceder hasta que finalice el paso del trabajo. En programas COBOL iSeries, el bloqueo permanece hasta que se produce un compromiso, que podría no suceder hasta el final de la unidad de ejecución, como se describe en Unidad de ejecución.

Registro MQ

Cuando se lee un registro MQ en una cola de mensajes con la palabra clave get, EGL realiza automáticamente estas operaciones:

  1. Se conecta al gestor de colas, si aún no lo está
  2. Abre la cola, si aún no está abierta
  3. Obtiene el próximo mensaje de la cola y traslada el contenido del mensaje a la estructura de registros de cola de mensajes. La cabecera del mensaje IMS (longitud, campo de información de control ZZ y código de transacción) se elimina automáticamente de cada registro leído de la cola.

En IMS, una sentencia get para un registro serie asignado a una cola de mensajes de segmento único da como resultado una llamada get unique (GU) al PCB de E/S. Esta llamada GU da como resultado un punto de compromiso automático. La primera sentencia get para un registro serie asignado a una cola de mensajes de varios segmentos da como resultado una llamada GU al PCB de E/S. Las sentencias get subsiguientes dan como resultado llamadas GN hasta que se alcanza una condición NRF (no se han encontrado registros en este nivel de segmento). La primera sentencia get después de NRF da como resultado otra llamada GU y el proceso continúa hasta que se alcanza una condición EOF. Cada llamada GU da como resultado un punto de compromiso automático.

Registro relativo

Si emite una sentencia get en un registro relativo, el elemento de clave asociado con el registro determina qué registro se recupera del archivo. El elemento de clave debe estar disponible para cualquier función que utilice el registro y puede ser cualquiera de los siguientes:
  • Un elemento del mismo registro
  • Un elemento de un registro que sea global con respecto al programa o local con respecto a la función que ejecuta la sentencia get
  • Un elemento de datos que sea global con respecto al programa o local con respecto a la función que ejecuta la sentencia get
Si desea sustituir o suprimir un registro indexado (o relativo), debe emitir una sentencia get para el registro y, a continuación, emitir la sentencia de cambio de archivo (replace o delete) sin que intervenga ninguna operación de E/S en el mismo archivo. Después de emitir la sentencia get, el resultado de la próxima operación de E/S en el mismo archivo será el siguiente:
  • Si la próxima operación de E/S es una sentencia replace en el mismo registro EGL, se cambia el registro del archivo
  • Si la próxima operación de E/S es una sentencia delete en el mismo registro EGL, el registro del archivo se marca para supresión
  • Si la próxima operación de E/S es una sentencia get en el mismo archivo (con la opción forUpdate), una sustitución o supresión subsiguiente es válida en el registro de archivo de lectura recién creado
  • Si la próxima operación de E/S es una sentencia get en el mismo archivo (sin la opción forUpdate) o es un cierre en el mismo archivo, el registro de archivo se libera sin cambios.

Registros serie

Una sentencia get lee el registro situado a continuación del último registro leído de la secuencia de entrada. El primer registro se lee para la primera exploración de un archivo. Si el registro al que se accede en la operación de E/S anterior era el último registro del archivo, la sentencia get devuelve EOF.

El archivo se cierra y se reabre siempre que el programa cambia de adición a lectura o de lectura a adición. Cuando se cierra el archivo, la posición del archivo se pierde; por tanto, la primera sentencia get después de una sentencia add leerá el primer registro del archivo. De forma parecida, una sentencia add a continuación de una sentencia get o get next añadirá un registro al principio del archivo.

En el entorno zSeries por lotes, una sentencia get para un registro serie asignado a un archivo GSAM da como resultado una llamada get next (GN) a la base de datos de GSAM. Si un registro serie de longitud variable está en un archivo asociado con GSAM y la longitud del registro es superior a la del archivo físico, DL/I devuelve un código de estado en blanco. Los datos se truncan pero no se emite ningún mensaje, ya que la situación no puede detectarse.

Registro SQL

La sentencia EGL get da como resultado una sentencia SQL SELECT en el código generado. Si especifica la opción singleRow, la sentencia SQL SELECT es una sentencia autónoma. La sentencia SQL SELECT también puede ser una cláusula de un cursor, como se describe en el apartado Soporte SQL.

Condiciones de error

Las condiciones siguientes se encuentran entre las que no son válidas al utilizar una sentencia get para leer datos de una base de datos relacional:
  • Se especifica una sentencia SQL de un tipo que no es SELECT
  • Especifica una cláusula SQL INTO directamente en una sentencia SQL SELECT
  • Además de una cláusula SQL INTO, especifica algunas cláusulas de una sentencia SQL SELECT, pero no todas
  • Especifica (o acepta) una sentencia SQL SELECT que está asociada con una columna que no existe o que es incompatible con la variable de lenguaje principal relacionada
Las siguientes condiciones de error se encuentran entre las que se producen al utilizar la opción forUpdate:
  • Especifica (o acepta) una sentencia SQL que muestra un intento de actualizar varias tablas; o
  • Utiliza un registro SQL como objeto de E/S, y todos los elementos de registro son de sólo lectura.
La situación siguiente también provoca un error:
  • Personaliza una sentencia EGL get con la opción forUpdate, pero no puede indicar que una columna de tabla SQL determinada está disponible para actualización; y
  • La sentencia replace que está relacionada con la sentencia get intenta revisar la columna.
Puede resolver la discrepancia anterior de cualquiera de estas formas:
  • Al personalizar la sentencia EGL get, incluya el nombre de columna en la sentencia SQL SELECT, cláusula FOR UPDATE OF; o
  • Al personalizar la sentencia EGL replace, elimine la referencia a la columna en la sentencia SQL UPDATE, cláusula SET; o
  • Acepte los valores por omisión para las sentencias get y replace.

Sentencia SQL SELECT implícita

Al especificar un registro SQL como objeto de E/S para la sentencia get, pero no especifica una sentencia SQL explícita, la sentencia SQL SELECT implícita tiene las siguientes características:

  • La propiedad específica de registro denominada defaultSelectCondition determina qué fila de tabla se selecciona, siempre y cuando el valor de cada columna de clave de tabla SQL sea igual al valor del elemento de clave correspondiente del registro SQL. Si no especifica una clave de registro ni una condición de selección por omisión, se seleccionan todas las filas de tabla. Si por alguna razón se seleccionan varias filas de tabla, la primera fila recuperada se coloca en el registro.
  • Como resultado de la asociación de elementos de registro y columnas de tabla SQL en la definición de registro, un elemento determinado recibe el contenido de la columna de tabla SQL relacionada.
  • Si especifica la opción forUpdate, la sentencia SQL SELECT FOR UPDATE no incluye elementos de registro que sean de sólo lectura.
  • La sentencia SQL SELECT de un registro determinado es similar a la sentencia siguiente, excepto que la cláusula SQL UPDATE sólo está presente si la sentencia get incluye la opción forUpdate:
      SELECT columna01, 
             columna02, ... 
             columnaNN
      FROM   nombreTabla 
      WHERE  columnaClave01 = :elementoClave01
      FOR UPDATE OF
             columna01, 
             columna02, ... 
             columnaNN
    La cláusula SQL INTO de la sentencia SQL SELECT autónoma o de la sentencia FETCH relacionada con el cursor es similar a esta:
      INTO   :elementoRegistro01,
             :elementoRegistro02, ...
             :elementoRegistroNN

    EGL deriva la cláusula SQL INTO si el registro SQL va acompañado de una sentencia SQL SELECT explícita cuando no se ha especificado una cláusula INTO. Los elementos de la cláusula INTO derivada son aquellos que están asociados con las columnas listadas en la cláusula SELECT de la sentencia SQL. (La asociación de elementos y columnas se encuentra en el componente de registro SQL, como se indica en el apartado Propiedades de elementos SQL). es necesaria una cláusula EGL INTO si no hay una columna asociada con un elemento.

Si especifica una matriz dinámica de registros SQL como objeto de E/S para la sentencia get, pero no especifica una sentencia SQL explícita, la sentencia SQL SELECT implícita es similar a la descrita para un solo registro SQL, con estas diferencias:
  • El componente de clave-valor de la consulta es un conjunto de relaciones que se basa en una condición de mayor-que-o-igual-que:
      columnaClave01 >= :elementoClave01 &
      columnaClave02 >= :elementoClave02 &
             .
             .
             .
      columnaClaveN  >= :elementoClaveN
  • Los elementos de la cláusula usingKeys (o las variables de lenguaje principal del registro SQL) no deben estar en el registro SQL que es la base de la matriz dinámica.
Comentarios
(C) Copyright IBM Corporation 2000, 2005. Reservados todos los derechos.