In PostgreSQL, every table name serves as type name for the row type (a.k.a. composite type) automatically - not as table type, there are no "table types" or "table variables" in Postgres (but there are typed tables).
So you can declare a variable of that type in 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
-- you can access columns with attribute notation like: q1.col1
END LOOP;
END LOOP;
END
$func$
You could also just declare variables of the generic type record
. It takes any row type at assignment automatically. But special rules apply. Be sure to follow the link and read the chapter of the manual!
A FOR
loop works with a built-in cursor. There are also explicit cursors in PL/pgSQL.
While it's often convenient to have the function return SETOF <table name>
, returning SETOF record
is not as convenient. The system does not know what the function returns this way and you have to add a column definition list with every call. Which is a pain. Details about table functions in the manual.
Often, there are more efficient solutions with plain SQL. Looping is a measure of last resort, when you can do things in one scan where you would need multiple scans in pure SQL.