Declarar variable de tipo de tabla en PL / pgSQL

8

Me pregunto si hay una manera de declarar una variable de tabla de tipos en PL / pgSQL para contener los resultados de la consulta. Por ejemplo, ¿cómo puedo expresar algo como:

q1 = select * from foo;
q2 = select * from bar;
for t1 in q1:
  for t2 in q2:
    -- do something with t1 and t2

Miré en la próxima construcción de retorno, pero parece que solo puede manejar valores de retorno.

JRR
fuente
2
PL / SQL => Oracle, PgPL / SQL => PostgreSQL. ¿Con cuál estás trabajando?
Mat
@ Mat: es PL / pgSQL , por cierto.
Erwin Brandstetter

Respuestas:

12

En PostgreSQL , cada nombre de tabla sirve como nombre de tipo para el tipo de fila (también conocido como tipo compuesto ) automáticamente; no es un tipo de tabla, no hay "tipos de tabla" o "variables de tabla" en Postgres ( pero hay tablas escritas ).
Entonces puedes declarar una variable de ese tipo PL/pgSQL.

CREATE FUNCTION foo()
 RETURNS void LANGUAGE plpgsql AS
$func$
DECLARE
  q1 foo;  -- "foo" ...
  q2 bar;  -- ... and "bar" are existing (visible) table names
BEGIN

FOR q1 IN 
   SELECT * from foo
LOOP
   FOR q2 IN 
      SELECT * from bar
   LOOP
       -- do something with q1 and q2
       -- since q1 and q2 are well known types, you can access columns
       -- with attribute notation. Like: q1.col1
   END LOOP;
END LOOP;

END
$func$

Un FORbucle funciona con un cursor incorporado. También hay cursores explícitos en plpgsql.

También podría simplemente declarar variables del tipo genérico record. Puede tomar cualquier tipo de fila en la asignación automáticamente. Pero se aplican reglas especiales. ¡Asegúrese de seguir el enlace y leer el capítulo del manual!

Si bien a menudo es conveniente que la función regrese SETOF <table name>, regresar SETOF recordno es tan conveniente. El sistema no sabe qué función devuelve de esta manera y debe agregar una lista de definición de columna con cada llamada. Lo cual es un dolor. Detalles sobre las funciones de la tabla en el manual .

Sin embargo, a menudo hay soluciones más eficientes con SQL simple. El bucle es una medida de último recurso, cuando puede hacer cosas en un escaneo en el que necesitaría múltiples escaneos en SQL puro.

Erwin Brandstetter
fuente
2
También tenga en cuenta que si desea devolver el tipo de tabla, puede decir algo comoCREATE FUNCTION footest() RETURNS SETOF foo LANGUAGE PLPGSQL AS $$...
Chris Travers
¿Por qué entonces tenemos la característica de "tipos compuestos" si podemos crear tablas en su lugar, sin restricciones aplicadas a los tipos compuestos (sin restricciones, etc.)? La única forma significativa de usar tipos compuestos que veo es devolver un par (o varios) parámetros de una función en lugar de crear una tabla completa para eso.
SaneDeveloper