2012-04-18 21 views
111

¿Hay una instrucción SQL para recuperar el valor de una secuencia que no la incrementa?¿Cómo recuperar el valor actual de una secuencia de oráculo sin incrementarlo?

Gracias.

EDITAR Y CONCLUSIÓN

Como se indica por Justin cueva No es útil tratar de "salvar" número de secuencia de modo

select a_seq.nextval from dual; 

es lo suficientemente bueno para comprobar un valor de secuencia.

Todavía mantengo la respuesta de Ollie como la buena porque respondió a la pregunta inicial. pero pregúntate sobre la necesidad de no modificar la secuencia si alguna vez quieres hacerlo.

+2

¿Por qué? ¿Cuál es el problema que estás tratando de resolver? Si está usando secuencias correctamente, nunca debería importar qué valores de secuencia se han asignado a otras sesiones o qué valores se pueden asignar a sesiones posteriores. –

+3

Es un control después de la migración de datos para asegurarse de que la secuencia se haya actualizado correctamente de acuerdo con los datos migrados – frno

+2

Entonces, ¿cuál es la desventaja de simplemente obtener el 'nextval' de la secuencia para probar? No estás asumiendo que las secuencias estarán libres de huecos, ¿verdad? Por lo tanto, "desperdiciar" un valor de secuencia no debería ser un problema. –

Respuesta

120
SELECT last_number 
    FROM all_sequences 
WHERE sequence_owner = '<sequence owner>' 
    AND sequence_name = '<sequence_name>'; 

Usted puede obtener una variedad de secuencia de metadatos de user_sequences, all_sequences y dba_sequences.

Estas vistas funcionan en todas las sesiones.

EDIT:

Si la secuencia está en su esquema predeterminado a continuación:

SELECT last_number 
    FROM user_sequences 
WHERE sequence_name = '<sequence_name>'; 

Si desea que todos los metadatos a continuación:

SELECT * 
    FROM user_sequences 
WHERE sequence_name = '<sequence_name>'; 

creo que sirve ...

EDIT2 :

Una manera de largo aliento de hacerlo de manera más fiable si el tamaño de la memoria caché no es 1 sería:

SELECT increment_by I 
    FROM user_sequences 
WHERE sequence_name = 'SEQ'; 

     I 
------- 
     1 

SELECT seq.nextval S 
    FROM dual; 

     S 
------- 
    1234 

-- Set the sequence to decrement by 
-- the same as its original increment 
ALTER SEQUENCE seq 
INCREMENT BY -1; 

Sequence altered. 

SELECT seq.nextval S 
    FROM dual; 

     S 
------- 
    1233 

-- Reset the sequence to its original increment 
ALTER SEQUENCE seq 
INCREMENT BY 1; 

Sequence altered. 

Sólo ten en cuenta que si los demás están usando la secuencia durante este tiempo - que (o usted) puede obtener

ORA-08004: sequence SEQ.NEXTVAL goes below the sequences MINVALUE and cannot be instantiated 

Además, es posible que desee establecer el caché a NOCACHE antes de la puesta a cero y luego de nuevo a su valor original después para asegurarse de que no haya almacenado en caché una gran cantidad de valores.

+0

Lo intenté pero no tengo acceso a la tabla 'all_sequences'. ¿Es un objeto especial que solo ves con credenciales de administrador? – frno

+0

Use user_sequences. Eso funcionará si tienes la secuencia que estás viendo. –

+1

'ALL_SEQUENCES' es una vista. Si no tiene acceso, intente seleccionar desde 'USER_SEQUENCES' si la secuencia está en su esquema predeterminado. (No necesitará la cláusula 'sequence_owner = ''' para 'USER_SEQUENCES'). – Ollie

98

select MY_SEQ_NAME.currval from DUAL;

Tenga en cuenta que sólo funciona si se ejecutó select MY_SEQ_NAME.nextval from DUAL; en las sesiones actuales.

+0

@fmo' cur rval' no modifica nada. [Sequence Pseudocolumns] (https://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns002.htm) – Linuslabo

0

Mi respuesta original era objetivamente incorrecta y me alegro de que se haya eliminado. El siguiente código funcionará bajo las siguientes condiciones a) usted sabe que nadie más modificó la secuencia b) la secuencia fue modificada por su sesión. En mi caso, me encontré con un problema similar cuando estaba llamando a un procedimiento que modificó un valor y estoy seguro de que la suposición es cierta.

SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL; 

Lamentablemente, si no ha modificado la secuencia en la sesión, creo que otros son lo cierto al afirmar que el NEXTVAL es el único camino a seguir.

Cuestiones relacionadas