return query sobre esquemas cambiantes

From: "Fernando Moreno" <azazel(dot)7(at)gmail(dot)com>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: return query sobre esquemas cambiantes
Date: 2008-04-30 20:27:51
Message-ID: b1c45530804301327x42eb613em5a588fc5c02e0c81@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Qué tal, hasta apenas un rato que comencé a utilizar la opción RETURN QUERY
en las funciones pl/pgsql. Estoy recibiendo datos incorrectos y no sé si lo
esté usando mal, les describiré la situación lo mejor posible:

* Manejamos múltiples sucursales, por medio de esquemas. Tenemos una tabla
public.sucursales donde almacenamos estos registros, además del nombre del
esquema.

* Dentro de cada esquema existen las tablas asientos y partidas, y una vista
llamada diario_gral, que combina las primeras dos tablas mas unos dos
ubicadas en public.

* El objetivo es desplazarse en los esquemas (modificando el search_path en
cada ciclo), consultar la vista (agregando dos campos), ir acumulando esos
resultados y enviarlos a la aplicación cliente.

La función es la siguiente:

CREATE OR REPLACE FUNCTION diario_gral_empresa(ej int,mes int) RETURNS setof
record AS $$
declare
rec record;
begin
for rec in select * from sucursales loop
execute 'set search_path to '||rec.esquema||',public';
return query select rec.idsuc,rec.nombre,d.* from diario_gral d where
d.id_ejercicio=ej and d.cns_mes=mes;
end loop;
return;
end;
$$ LANGUAGE 'plpgsql';

Al ejecutar la función, el ciclo se ejecuta tres veces, pero en los últimos
dos tenemos datos repetidos que pertenecen al primer ciclo de ejecución, lo
que si va cambiando son los dos valores que agregamos directamente y que
provienen de la variable record (idsuc y nombre) .

Reemplacé RETURN QUERY con un FOR record IN SELECT ... sobre la vista (el
método antiguo) y los mostré en pantalla con RAISE NOTICE. El resultado es
el mismo, cada ciclo interior se suponía que mostrara un registro distinto
generado por la vista, pero muestra los mismos datos generados por el primer
ciclo FOR exterior (el que cambia entre esquemas). Al final probé algo como
esto:

execute 'set search_path to '||'sucursal008'||',public';
return query select 8,'sucursal8'::text,d.* from diario_gral d where
d.id_ejercicio=ej and d.cns_mes=mes;

Esta vez no usé ciclos, solo para verificar el funcionamiento de RETURN
QUERY (ejecutado una sola vez) y todo bien, regresó los datos completos de
un esquema.

Después recordé que hace poco tuve un problema al insertar datos en tablas
temporales creadas con la opción ON COMMIT DROP (para eliminarse al terminar
la transacción), y encontré que era una falla de postgres al guardar
referencias a esas tablas temporales eliminadas y no "replanificar" las
consultas en ejecuciones posteriores de la misma función. En su momento lo
solucioné tal como señalaban los diversos comentarios en foros y listas de
correo: con EXECUTE. El problema parece ser el mismo, pues el cambio
dinámico de search_path parece no afectar como debe ser a la consulta
realizada por RETURN QUERY SELECT..., quizás la única forma de señalar el
esquema explícitamente en esta consulta, sea con una estructura dinámica
como la usada en FOR record in EXECUTE cadena, pero no está disponible para
RETURN QUERY.

¿Alguien más ha usado RETURN QUERY con los mismos problemas? ¿Podría ser un
error en postgres?

---Agrego:
He probado dos bloques que modificaban el search_path, seguido de un RETURN
QUERY y los resultados son correctos. Algo así:

execute 'set search_path to '||'sucursal008'||',public';
return query select 8,'sucursal8'::text,d.* from diario_gral d where
d.id_ejercicio=ej and d.cns_mes=mes;

execute 'set search_path to '||'sucursal002'||',public';
return query select 2,'sucursal2'::text,d.* from diario_gral d where
d.id_ejercicio=ej and d.cns_mes=mes;

Lo que hace parecerse aún más al problema de las tablas temporales, pues en
esa ocasión pude hacer funcionar los INSERT literalmente uno tras otro, pero
el ejecutarlos dentro de un ciclo no.

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Juan Manuel Fernandez 2008-04-30 20:37:43 Manejar tablas de Log
Previous Message Edwin Quijada 2008-04-30 19:48:42 RE: Transacciones en PG