Hola,
Código:
SET TERM !! ;
CREATE PROCEDURE Establecer_GENERADOR_X (
ParNuevoValor INTEGER)
AS
DECLARE VARIABLE ValorActual INTEGER;
BEGIN
/* 1 .. recuperamos el valor actual del generador */
ValorActual = GEN_ID(GENERADOR_X, 0);
/* 2 .. fijamos el nuevo valor del generador */
ValorActual = GEN_ID(GENERADOR_X, (:ParNuevoValor) - :ValorActual);
END !!
SET TERM ; !!
Lo que hace es aprovecharse de la posibilidad de leer (pero no modificar) el valor actual de un generador (/* 1 .. */), y que los generadores pueden tomar saltos mayores que 1 y negativos, si es necesario (/* 2 .. */).
Hay una pega, Si DESPUES de recuperar el valor actual del generador (/* 1 .. */) y ANTES de fijar el nuevo valor (/* 2 .. */), otro usuario hiciese "saltar" el generador (hacia delante, o hacia atrás), ya no se podría garantizar que el generador quedará fijado al valor que pasamos como parámetro al procedimiento. Esto es debido a que los generadores (y por extensión la función GEN_ID) no están sujetos al control de la transacción que los modifica. En entornos de un sólo usuario (o que garanticemos que cuando se utilice el procedimiento sólo hay un usuario conectado a la base de datos), el procedimiento funcionará correctamente, en entornos multiusuario no es posible garantizarlo.
Saludos.