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ú]


--
TIP 4: No hagas 'kill -9' a postmaster

Responder a