Oráculo – Secuencias

Secuencias Oracle Enciclopedia

Oracle

Oracle

Funcionamiento

Arquitectura

Fichas

Procesos

La Memoria

Diccionario de datos

Secuencias

Consultas jerárquicas

Este artículo está basado en la versión 8.1.6 de Oracle.

Una secuencia es un objeto de la base de datos Oracle, al igual que una tabla, una vista, etc. Es decir, pertenece a un usuario, podemos manipularlo, modificarlo, siempre que tengamos los derechos necesarios. Este artículo pretende definir qué es una secuencia y presentar las posibilidades que ofrece este objeto.

Definición de una secuencia

Definir una secuencia es equivalente a definir una secuencia de enteros. La evolución de esta secuencia se rige por una serie de parámetros, que veremos juntos un poco más adelante.Utilizar una secuencia nos permite, por tanto, disponer de una secuencia de valores. Esto se puede utilizar para:

  • generar claves únicas en las tablas
  • tener un contador de información, que incrementamos cuando queramos
  • etc…
    • Mi primera secuencia

      Dado que la mayoría de los parámetros tienen un valor por defecto, no es necesario especificarlos todos cuando queremos crear una nueva secuencia. Así que aquí está la orden SQL mínima para crear una secuencia:

CREATE SEQUENCE ma_sequence;

En esta orden, «mi_secuencia» es obviamente el nombre de la secuencia que se quiere crear; una secuencia tiene un nombre, igual que una tabla, o cualquier otro objeto en Oracle. Si ejecuta este comando SQL y si tiene los privilegios necesarios (es decir, CREATE SEQUENCE), Oracle responderá amablemente «Sequence created». ¿Pero cómo se ve lo que hay en esa secuencia? ¿Cómo explotarlo?

La interrogación de una secuencia se realiza utilizando las «pseudocolumnas» CURRVAL y NEXTVAL. Se llama pseudocolumna porque se maneja un poco como una columna de tabla, pero no es una columna de tabla.

  • La pseudocolumna CURRVAL devuelve el valor actual de la secuencia.
  • La pseudocolumna NEXTVAL incrementa la secuencia y devuelve el nuevo valor.
    • Ejemplos:
===SQL> select ztblseq.currval from dual;select ztblseq.currval from dual*ERREUR à la ligne 1 :ORA-08002: séquence ZTBLSEQ.CURRVAL pas encore définie dans cette session===

Este error se debe a que aún no hemos inicializado nuestra secuencia y estamos intentando recuperar el valor actual.

Cuando se utiliza una secuencia por primera vez, se debe utilizar NEXTVAL para inicializarla.

===SQL> select ztblseq.nextval from dual; NEXTVAL---------1===

CURRVAL ahora devuelve 1. Si es así, prueba…

===SQL> select ztblseq.currval from dual; CURRVAL---------1===

Ahora que sabemos cómo recuperar el valor de una secuencia, y sabemos cómo incrementarla, vamos a ver cuáles son los diferentes parámetros que nos permiten definir una secuencia:

Identificador de secuencia

Dentro de una misma base de datos, varios objetos pueden tener el mismo nombre, siempre que cada uno esté en un esquema diferente. Además, es posible especificar en qué esquema se desea crear la secuencia:

CREATE SEQUENCE schema_toto.sequence_de_toto;

Valor inicial e incremento

Por defecto, una secuencia comienza con el valor 1, y se incrementa de 1 en 1 en cada llamada a NEXTVAL. Pero uno puede especificar perfectamente sus propios parámetros:

CREATE SEQUENCE ma_sequence START WITH 5 INCREMENT BY 3;

En este ejemplo, hemos definido la secuencia 5, 8, 11, 14, 17, 20…
Los parámetros COMENZAR CON e INCREMENTAR POR se pueden utilizar independientemente.
Para hacer una secuencia descendente, basta con especificar un valor negativo al parámetro INCREMENT BY:

CREATE SEQUENCE ma_sequence INCREMENT BY -10;

Valor máximo y valor mínimo

Implícitamente (por defecto), Oracle ha creado nuestra primera secuencia con los siguientes parámetros (entre otros):

CREATE SEQUENCE ma_sequence NOMAXVALUE NOMINVALUE;

Si se desea, podemos establecer un techo (para una secuencia ascendente) o un suelo (para una secuencia descendente):

CREATE SEQUENCE ma_sequence START WITH 1 INCREMENT BY 1 MAXVALUE 9999;CREATE SEQUENCE ma_sequence START WITH -1 INCREMENT BY -1 MINVALUE -9999;

Looping the sequence

Cuando la secuencia alcanza su valor máximo (resp. mini), se le puede pedir que se detenga (Oracle devolverá un error en el siguiente intento de usar NEXTVAL), o que se reanude en su valor mini (resp. máximo) y reanude su conteo.
Esta secuencia contará hasta 10 y luego devolverá un error en el siguiente NEXTVAL:

CREATE SEQUENCE ma_sequence START WITH 1 MINVALUE -10 MAXVALUE 10 NOCYCLE;

Esta secuencia contará de 1 a 10, luego de -10 a 10, luego de -10 a 10… :

CREATE SEQUENCE ma_sequence START WITH 1 MINVALUE -10 MAXVALUE 10 CYCLE;

Por defecto, una secuencia no hace un bucle de retorno (caso #1)

Cachear valores

Para optimizar el uso de las secuencias, se puede indicar a Oracle que guarde en caché un determinado número de valores de la secuencia:

CREATE SEQUENCE ma_sequence CACHE 100;

Por defecto, Oracle mantiene 20 valores en caché.

¿Es importante el almacenamiento en caché?
Sí, puede tener un efecto significativo en el rendimiento. Se puede poner un número elevado de valores en la caché.

Forzar el orden de creación

Este ajuste sólo afecta a los servidores que funcionan en modo paralelo. Para comprobarlo, ejecute el siguiente comando SQL:

SELECT name, value FROM v$parameter WHERE name = 'parallel_server';

Si está ejecutando en modo paralelo (TRUE), cuando se ejecutan múltiples NEXTVAL simultáneamente, no siempre se procesan en el orden correcto. Además, es necesario habilitar la opción ORDER de la siguiente manera:

CREATE SEQUENCE ma_sequence ORDER;

Edición de una secuencia

En los ejemplos anteriores, vimos cómo crear una secuencia especificando atributos que definen su comportamiento. Estos atributos pueden ser modificados después de la creación de la secuencia. Todo lo que tienes que hacer es utilizar el comando SQL ALTER SEQUENCE.Aquí hay un ejemplo de encadenamiento de comandos SQL:

===SQL> create sequence ma_sequence start with 1 minvalue 0;Séquence créée.SQL> select ma_sequence.nextval from dual; NEXTVAL---------1SQL> select 'La valeur courante est ' || ma_sequence.currval from dual;'LAVALEURCOURANTEEST'||MA_SEQUENCE.CURRVAL---------------------------------------------------------------La valeur courante est 1SQL> alter sequence ma_sequence increment by 20;Séquence modifiée.SQL> select ma_sequence.nextval from dual; NEXTVAL--------- 21SQL> select ma_sequence.nextval + ma_sequence.nextval from dual;MA_SEQUENCE.NEXTVAL+MA_SEQUENCE.NEXTVAL--------------------------------------- 82SQL> alter sequence ma_sequence increment by -41 maxvalue 100 cycle nocache;Séquence modifiée.SQL> select ma_sequence.nextval from dual; NEXTVAL---------0SQL> select ma_sequence.nextval from dual; NEXTVAL--------- 100SQL> select ma_sequence.nextval from dual; NEXTVAL--------- 59===

¿Te has dado cuenta de que cuando se ejecuta «select my_sequence.nextval + my_sequence.nextval from dual;», sólo se utiliza un mismo valor de secuencia? Oracle considera a NEXTVAL como una pseudocolumna, y por lo tanto en este comando SQL, sólo la «recoge» una vez a nivel de base de datos, la segunda vez recoge el valor cargado en memoria.

Modificación de una secuencia

Una pregunta que surge mucho en los foros de Oracle es «¿Cómo puedo crear una columna de tabla autoincrementable, con el fin de convertirla en clave primaria?». De hecho, Oracle no tiene la opción de auto_incremento que se encuentra en algunos SGBD (incluido MySQL).

El principio es el siguiente:

  • crear una secuencia que genere valores enteros únicos
  • crear un TRIGGER que se dispare en cada INSERT, para alimentar el campo deseado con un valor único.

Aquí tienes un ejemplo de trigger:

===create trigger t_matable_pkbefore insert on matable for each rowbegin select seq_matable_pk.nextval into :new.x from dual;end;===

… donde «x» es el nombre del campo que se autoincrementa.

Este ejemplo no maneja la comprobación de unicidad del valor que vamos a insertar,pero si el campo se alimenta SOLO utilizando la secuencia dedicada a él,y si esta secuencia no está configurada para hacer un bucle de vuelta,no hay razón para que se produzca un error de clave duplicada…

¿Una secuencia sin agujeros?

Dado que una secuencia puede ser consultada en cualquier momento por cualquier usuario de Oracle con derechos suficientes, las SECUENCIAS NO DEBEN ser consideradas como una forma de generar una secuencia de números sin «agujeros». Ejemplo: en el caso de una alimentación de clave primaria, si se insertó un registro y luego se retrocedió la transacción, entonces la secuencia no retrocede, y la próxima vez que se inserte, parecerá que la secuencia se saltó uno o más números.Así pues: una secuencia proporciona una forma de obtener valores únicos, pero no necesariamente continuos.

Bibliografía

  • Documentación de Oracle: http://www.oradoc.com
  • Esquema de la sintaxis de CREATE SEQUENCE: http://www.oradoc.com/ora816/server.816/a76989/ch4g23.gif

Artículo escrito por Tittom

Trucos & relevantes encontrados en la base de conocimientos

22/09 6:56 PM Conexión a una base de datos Oracle en php (Oracle)
Oracle Más consejos sobre «Oracle»

Discusiones relevantes encontradas en el foro

20/06 5:48 PM importar base de datos oracle Importar base de datos oracle Desarrollo 17/02 9:48 AM->abdou 9
31/05 16:27 lista de campos de oracle sql Lista de campos Desarrollo 9/18 13:00-.>yannick 8 09/02 2:57 PM base preexistente del modelo uml de Oracle base preexistente del modelo Desarrollo 05/12 01:55-.>artaud 8 03/24 13:41 personal oracle 8 personal oracle 8 Software/Drivers 03/26 10:17am-.>yanban 7 07/04 02:10 AM instalación de oracle 8i windows xp Pb instalando oracle 8i en windows XP Windows 12/01 15:32-.>loulou 7 02/12 3:59pm horas de comparación de Oracle horas de comparación Desarrollo 09/02 2:03pm-.>Gilles M 5 08/03 12:04pm documento bd de Oracle.form.submit document.form.submit() Desarrollo 12/03 11:36am->renisaac 5 08/02 11:08 AM acceso a importar datos de oracle importar datos de oracle Software/Controladores 10/02 6:27 pm->random 4 11/11 5:06pm desarrollador de Oracle Desarrollo Desarrollo 11/11 6:16pm-.>fagy 4 02/15 8:08pm bases de datos de oracle Pregunta en Bases de datos de ORACLE Desarrollo 23 de febrero 12:21pm-.>Alex75 4 Discusión cerrada Problema resuelto Oracle No hay más discusión sobre «Oracle»

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *