I need to loop through type RECORD items by key/index, like I can do this using array structures in other programming languages.
For example:
DECLARE
data1 record;
data2 text;
...
BEGIN
...
FOR data1 IN
SELECT
*
FROM
sometable
LOOP
FOR data2 IN
SELECT
unnest( data1 ) -- THIS IS DOESN'T WORK!
LOOP
RETURN NEXT data1[data2]; -- SMTH LIKE THIS
END LOOP;
END LOOP;
As @Pavel explained, it is not simply possible to traverse a record, like you could traverse an array. But there are several ways around it – depending on your exact requirements. Ultimately, since you want to return all values in the same column, you need to cast them to the same type –
textis the obvious common ground, because there is a text representation for every type.Quick and dirty
Say, you have a table with an
integer, atextand adatecolumn.Then the solution can be a simple as:
Works for the first two rows, but fails for the special cases of row 3 and 4.
You can easily solve the problem with commas in the text representation:
This would work fine – except for line 4 which has double quotes in the text representation. Those are escaped by doubling them up. But the array constructor would need them escaped by
\. Not sure why this incompatibility is there …Yields:
But you would need:
Proper solution
If you knew the column names beforehand, a clean solution would be simple:
Since you operate on records of well know type you can just query the system catalog:
Put this in a function with dynamic SQL:
Call:
Returns:
This works without installing additional modules. Another option is to install the hstore extension and use it like @Craig demonstrates.