====== Oracle ====== Pues sí, inicio esta página dedicada a truquillos de oracle: poner el "nextval" en un número de secuencia. * [[fixhtml|Fix or sanitize HTML code from oracle]] * [[dsnWithNoPasswordAsking|Configure an ODBC Data Source with no password request]] * [[meaningOfFullJoin|How does full join work???]] ====== Poner el valor siguiente (nextval) en un número de secuencia ====== Si sois lo suficientemente osados para consultar la [[http://download.oracle.com/docs/cd/B14117_01/index.htm|documentacion de Oracle]], en concreto el apartado dedicado al [[http://download-uk.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_2011.htm|comando ALTER SEQUENCE]], vereis con desagrado que ¡oh desgracia! se puede cambiar de todo menos el valor actual. Para más recochineo, el manual dice explicitamente: To restart the sequence at a different number, you must drop and re-create it. Vamos, que no se les ha olvidado: los muy... lo han hecho aposta. La gente ha ido dándole vueltas al coco y ha dado con una solución a este problema: * obtenemos el siguiente valor mediante un select ... into X * ponemos que el incremento de la secuencia es -X * ...y hacemos secuencia.nextval, con lo cual vuelve a cero * ponemos el incremento de la secuencia de nuevo en 1 * y ya está, la secuencia inicializada Yo le he dado una vuelta de tuerca a este asunto y he mejorado el script reset_seq que ponían [[http://stackoverflow.com/questions/51470/how-do-i-reset-a-sequence-in-oracle|en esta página]]: el mío permite inicializar la secuencia **en cualquier número que establezcamos**: es perfecto para volver al redil a esas secuencias que se han descoordinado con respecto a su tabla "amiga". Sin más, ahí va el script: create or replace procedure reset_seq( p_seq_name in varchar2, p_newnumber in number ) is l_nextval number; l_minus number; l_newnumber number; begin execute immediate 'select ' || p_seq_name || '.nextval from dual' INTO l_nextval; l_newnumber := p_newnumber - 1; l_minus := l_nextval - l_newnumber; l_minus := l_minus * -1; --dbms_output.put_line( 'l_nextval: ' || l_nextval ); --dbms_output.put_line( 'l_newnumber: ' || l_newnumber ); --dbms_output.put_line( 'resultado minus: ' || l_minus ); if l_minus <> 0 then execute immediate 'alter sequence ' || p_seq_name || ' increment by ' || l_minus || ' minvalue 0'; execute immediate 'select ' || p_seq_name || '.nextval from dual' INTO l_nextval; execute immediate 'alter sequence ' || p_seq_name || ' increment by 1 minvalue 0'; end if; end; Como veis, tampoco me he matado. Un consejo: si quisieramos ser puristas, no hay porqué suponer que las secuencias se autoincrementan en uno, podrían hacerlo en otro valor. Entonces habría que recuperar el valor de autoincremento antes de cambiarlo y luego restablecerlo por el que hemos almacenado. Pero bueno, con esto era suficiente para mi gestión. Espero que os sirva.