Referencia de secuencia

Una referencia de frecuencia es una expresión que hace referencia a una secuencia definida en el servidor de aplicaciones.

referencia-secuencia
Leer el esquema de sintaxisOmitir el esquema de sintaxis visualexpresión-nextvalexpresión-prevval
expresión-nextval
Leer el esquema de sintaxisOmitir el esquema de sintaxis visualNEXT VALUE FORnombre-secuencia
expresión-prevval
Leer el esquema de sintaxisOmitir el esquema de sintaxis visualPREVIOUS VALUE FORnombre-secuencia
NEXT VALUE FOR nombre-secuencia
Una expresión NEXT VALUE genera y devuelve el siguiente valor de la secuencia especificada por nombre-secuencia.
PREVIOUS VALUE FOR nombre-secuencia
Una expresión PREVIOUS VALUE devuelve el valor generado más recientemente de la secuencia especificada para una sentencia anterior del proceso de aplicación actual. Se puede hacer referencia a este valor repetidamente utilizando expresiones PREVIOUS VALUE que especifican el nombre de la secuencia. Pueden existir múltiples instancias de las expresiones PREVIOUS VALUE especificando el mismo nombre de secuencia en una sola sentencia; todas ellas devuelven el mismo valor. En un entorno de base de datos particionada, es posible que una expresión PREVIOUS VALUE no devuelva el valor generado más recientemente.

Una expresión PREVIOUS VALUE sólo se puede utilizar si ya se ha hecho referencia a una expresión NEXT VALUE que especifica el mismo nombre de secuencia en el proceso de aplicación actual, ya sea en la transacción actual ya sea en una transacción anterior (SQLSTATE 51035).

Notas

  • Autorización: Si se utiliza una referencia-secuencia en una sentencia, los privilegios del ID de autorización de la sentencia deben incluir, como mínimo, uno de los privilegios siguientes:
    • El privilegio USAGE sobre la secuencia
    • Autorización DATAACCESS
  • Se genera un valor nuevo para una secuencia cuando la expresión NEXT VALUE especifica el nombre de dicha secuencia. Sin embargo, si existen múltiples instancias de una expresión NEXT VALUE que especifican el mismo nombre de secuencia en una consulta, el contador para la secuencia se incrementa sólo una vez para cada fila del resultado y todas las instancias de NEXT VALUE devuelven el mismo valor para una fila del resultado.
  • Se puede utilizar el mismo número de secuencia como valor de clave de unicidad en dos tablas independientes haciendo referencia al número de secuencia con una expresión NEXT VALUE para la primera fila (esto genera el valor de secuencia) y una expresión PREVIOUS VALUE para las demás filas (la instancia de PREVIOUS VALUE hace referencia al valor de secuencia generado más recientemente en la sesión actual), tal y como se muestra en el ejemplo siguiente:
       INSERT INTO order(orderno, cutno)
         VALUES (NEXT VALUE FOR order_seq, 123456);
    
       INSERT INTO line_item (orderno, partno, quantity)
         VALUES (PREVIOUS VALUE FOR order_seq, 987654, 1);
  • Las expresiones NEXT VALUE y PREVIOUS VALUE pueden especificarse en los lugares siguientes:
    • sentencia-select o sentencia SELECT INTO (en la cláusula-select, a condición de que la sentencia no contenga una palabra clave DISTINCT, una cláusula GROUP BY, una cláusula ORDER BY, una palabra clave UNION, una palabra clave INTERSECT o una palabra clave EXCEPT)
    • sentencia INSERT (en una cláusula VALUES)
    • sentencia INSERT (en la cláusula-select de la selección completa (fullselect))
    • sentencia UPDATE (en la cláusula SET (una sentencia UPDATE buscada o colocada), excepto que no se puede especificar NEXT VALUE en la cláusula-select de la selección completa de una expresión de la cláusula SET)
    • sentencia SET variable (excepto en la cláusula-select de la selección completa de una expresión; una expresión NEXT VALUE puede especificarse en un activador, pero una expresión PREVIOUS VALUE no puede especificarse)
    • sentencia VALUES INTO (en la cláusula-select de la selección completa (fullselect) de una expresión)
    • sentencia CREATE PROCEDURE (en el cuerpo-rutina de un procedimiento SQL)
    • sentencia CREATE TRIGGER en la acción-activada (se puede especificar una expresión NEXT VALUE, pero no se puede especificar una expresión PREVIOUS VALUE)
  • Las expresiones NEXT VALUE y PREVIOUS VALUE no se pueden especificar (SQLSTATE 428F9) en los lugares siguientes:
    • Las condiciones de unión de una unión externa completa
    • El valor DEFAULT de una columna en una sentencia CREATE o ALTER TABLE
    • La definición de columna generada en una sentencia CREATE o ALTER TABLE
    • La definición de tabla de resumen de una sentencia CREATE TABLE o ALTER TABLE
    • La condición de una restricción CHECK
    • Sentencia CREATE TRIGGER (se puede especificar una expresión NEXT VALUE, pero no se puede especificar una expresión PREVIOUS VALUE)
    • CREATE VIEW, sentencia
    • CREATE METHOD, sentencia
    • CREATE FUNCTION, sentencia
    • Una lista de argumentos de una expresión XMLQUERY, XMLEXISTS o XMLTABLE
  • Además, no se puede especificar una expresión NEXT VALUE (SQLSTATE 428F9) en los lugares siguientes:
    • Expresión CASE
    • La lista de parámetros de una función agregada
    • La subconsulta en un contexto distinto de los explícitamente permitidos, tal y como se describe anteriormente
    • La sentencia SELECT para la que la SELECT externa contiene un operador DISTINCT
    • La condición de unión de una unión
    • La sentencia SELECT para la que la SELECT externa contiene una cláusula GROUP BY
    • La sentencia SELECT para la que la SELECT externa está combinada con otra sentencia SELECT utilizando el operador establecido UNION, INTERSECT o EXCEPT
    • Una expresión de tabla anidada
    • La lista de parámetros de una función de tabla
    • La cláusula WHERE de la sentencia SELECT más externa o una sentencia DELETE o UPDATE
    • La cláusula ORDER BY de la sentencia SELECT más externa
    • La cláusula-select de la selección completa (fullselect) de una expresión, en la cláusula SET de una sentencia UPDATE
    • La sentencia IF, WHILE, DO ... UNTIL o CASE de una rutina de SQL
  • Cuando se genera un valor para una secuencia, se consume dicho valor y, la siguiente vez que se solicita un valor, se genera un valor nuevo. Esto es válido incluso cuando la sentencia que contiene la expresión NEXT VALUE falla o se retrotrae.

    Si una sentencia INSERT incluye una expresión NEXT VALUE en la lista VALUES para la columna y si se produce un error en algún punto durante la ejecución de INSERT (puede ser un problema al generar el siguiente valor de secuencia o un problema con el valor de otra columna), se produce una anomalía de inserción (SQLSTATE 23505) y se considera que el valor generado para la secuencia se ha consumido. En algunos casos, al volver a emitir la misma sentencia INSERT se puede obtener un resultado satisfactorio.

    Por ejemplo, considere un error que es el resultado de la existencia de un índice de unicidad para la columna para la que se ha utilizado NEXT VALUE y el valor de secuencia generado ya existe en el índice. Es posible que el siguiente valor generado para la secuencia sea un valor que no existe en el índice y, por consiguiente, el INSERT subsiguiente dará un resultado satisfactorio.

  • Ámbito de PREVIOUS VALUE: El valor de PREVIOUS VALUE se mantiene hasta que el valor siguiente se genera para la secuencia en la sesión actual, la secuencia se descarta o se modifica, o hasta que finaliza la sesión de la aplicación. El valor no se ve afectado por las sentencias COMMIT o ROLLBACK. El valor de PREVIOUS VALUE no puede establecerse directamente y es el resultado de ejecutar la expresión NEXT VALUE para la secuencia.

    Una técnica utilizada habitualmente, sobre todo para cuestiones de rendimiento, es que una aplicación o producto gestione un conjunto de conexiones y direccione transacciones a una conexión arbitraria. En estas situaciones, la disponibilidad de PREVIOUS VALUE para una secuencia solamente debería ser dependiente hasta que finalice la transacción. Algunos ejemplos de dónde puede producirse este tipo de situación incluyen aplicaciones que utilicen protocolos XA, usen la agrupación de conexiones, empleen el concentrador de conexiones y utilicen HADR para lograr la migración tras error.

  • Si al generar un valor para una secuencia se excede el valor máximo para la secuencia (o el valor mínimo para una secuencia descendente) y no se permiten ciclos, se producirá un error (SQLSTATE 23522). En este caso, el usuario puede modificar (ALTER) la secuencia para ampliar el rango de valores aceptables, habilitar ciclos para la secuencia o descartar (DROP) la secuencia y crear (CREATE) una nueva con un tipo de datos diferente que tenga un mayor rango de valores.

    Por ejemplo, una secuencia puede haberse definido con un tipo de datos de SMALLINT y, finalmente, la secuencia se queda sin valores asignables. Descarte (DROP) y vuelva a crear la secuencia con la nueva definición para volver a definir la secuencia como INTEGER.

  • Una referencia a una expresión NEXT VALUE en la sentencia de selección (select) de un cursor hace referencia a un valor que se genera para una fila de la tabla resultante. Se genera un valor de secuencia para una expresión NEXT VALUE para cada fila que se busca desde la base de datos. Si se realiza el bloqueo en el cliente, puede que los valores se hayan generado en el servidor con anterioridad al proceso de la sentencia FETCH. Esto puede producirse cuando existe bloqueo de las filas de la tabla resultante. Si la aplicación cliente no capta (FETCH) explícitamente todas las filas que la base de datos ha materializado, la aplicación no verá los resultados de todos los valores de secuencia generados (para las filas materializadas que no se ha devuelto).
  • Una referencia a una expresión PREVIOUS VALUE de la sentencia de selección de un cursor hace referencia a un valor que se ha generado para la secuencia especificada con anterioridad a la apertura del cursor. Sin embargo, el cierre del cursor puede afectar a los valores devueltos por PREVIOUS VALUE para la secuencia especificada en las sentencias futuras o incluso para la misma sentencia en el caso de que se vuelva a abrir el cursor. Esto sucederá cuando la sentencia de selección del cursor incluya una referencia a NEXT VALUE para el mismo nombre de secuencia.

Ejemplos

Supongamos que existe una tabla llamada "order" y que se crea una secuencia llamada "order_seq" del modo siguiente:
   CREATE SEQUENCE order_seq
     START WITH 1
     INCREMENT BY 1
     NO MAXVALUE
     NO CYCLE
     CACHE 24
A continuación se muestran algunos ejemplos de cómo generar un número de secuencia "order_seq" con una expresión NEXT VALUE:
   INSERT INTO order(orderno, custno)
     VALUES (NEXT VALUE FOR order_seq, 123456);
o
   UPDATE order
     SET orderno = NEXT VALUE FOR order_seq
     WHERE custno = 123456;
o
   VALUES NEXT VALUE FOR order_seq INTO :hv_seq;