reiniciar todas las secuencias de un esquema

From: "Arturo Munive [pgsql-es-ayuda] " <arturomunive(at)gmail(dot)com>
To: Postgresql <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: reiniciar todas las secuencias de un esquema
Date: 2008-10-06 22:28:09
Message-ID: 48EA90F9.80106@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Hoy nuevamente me encuentro en un proyecto con postgresql y me encontré
con una vieja molestia que decidí resolver...

muchas veces cuando uno hace pruebas en desarrollo de una BD inserta y
borra datos.
luego cuando va a poner la base en producción o quiere "hacer mas
pruebas" uno desea volver a reiniciar las secuencias
de las tablas, cosa que es demasiado fastidiosa hacer a mano (muchos
setval) para mi gusto

por eso quiero compartirles (no se si ya se hizo o hay otra forma mejor)
un par de funciones que se comportan bien (al menos en mis pocas pruebas)
se basa en un par de supuestos:
a) las PK de cada tabla se llaman id y son seriales
b) las secuencias se dejan con su nombre por defecto tabla_id_seq para
una tabla llamada "tabla" y una pk serial llamada "id"

supongo que hay formas mejores, ademas esto no se si funciona en
versiones menores a 8.3
seria bueno si alguien la prueba en otras versiones, las modifica les
mete mano y las vuelve a publicar

bueno aqui van

--------------------------------------------------------------------------------------------------------
-- La primera solo me da el máximo valor de id dado el nombre de una tabla
--------------------------------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION "public"."max_id" (tabla text) RETURNS integer AS
$body$
DECLARE
id_maximo INTEGER;
resultado REFCURSOR;
consulta TEXT;

BEGIN

id_maximo = 0;
consulta = 'SELECT max(id) FROM ' || tabla;--quote_ident(tabla);

OPEN resultado FOR EXECUTE consulta;

FETCH resultado INTO id_maximo;

CLOSE resultado;

RETURN id_maximo;

END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

--------------------------------------------------------------------------------------------------------
-- la segunda establece la secuencia al siguiente numero de id que
seguiría según los datos que queda en la tabla
--------------------------------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION "public"."reset_seq" (tabla text) RETURNS
varchar AS
$body$
DECLARE
consulta text;
id integer;
BEGIN
id = coalesce(max_id(tabla),0)+1;
consulta = 'select setval('''||tabla||'_id_seq'','||id||',false)';
EXECUTE consulta;

RETURN consulta;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

--------------------------------------------------------------------------------------------------------
-- la tercera busca los nombres de las tablas en una secuencia y para
cada una de ellas va ejecutando la función anterior
--------------------------------------------------------------------------------------------------------

DECLARE
tabla text;
nombres_tablas
cursor (nombre_esquema text) FOR
select schemaname||'.'||tablename from pg_tables where schemaname =
nombre_esquema;

BEGIN
OPEN nombres_tablas(esquema);
LOOP
FETCH nombres_tablas INTO tabla;
EXIT WHEN NOT FOUND;
--RAISE NOTICE '%',tabla;
PERFORM public.reset_seq(tabla);
END LOOP;

END;

--------------------------------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------------------------------

Espero les sea útil

Saludos.

--
---------------------------------------------------------
ARTURO MUNIVE SOLIS
Telefono: (51-54)424701
Celular : (51-54)959992034
[Desarrollo De Soluciones Java-PostgreSQL Arequipa-Perú]

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Juan Carlos Villalobos C 2008-10-07 04:44:43 Sincronizar BDs
Previous Message Jenaro Centeno Gómez 2008-10-06 17:44:26 Re: usar tipo money o real en proceso de facturacion ?