I'm attempting to write an area of a function in PL/pgSQL that loops through an hstore
and sets a record's column(the key of the hstore
) to a specific value (the value of the hstore
). I'm using Postgres 9.1.
The hstore
will look like: ' "column1"=>"value1","column2"=>"value2" '
Generally, here is what I want from a function that takes in an hstore
and has a record with values to modify:
FOR my_key, my_value IN
SELECT key,
value
FROM EACH( in_hstore )
LOOP
EXECUTE 'SELECT $1'
INTO my_row.my_key
USING my_value;
END LOOP;
The error which I am getting with this code:
"myrow" has no field "my_key"
. I've been searching for quite a while now for a solution, but everything else I've tried to achieve the same result hasn't worked.
Simpler alternative to your posted answer. Should perform much better.
This function retrieves a row from a given table (
in_table_name
) and primary key value (in_row_pk
), and inserts it as new row into the same table, with some values replaced (in_override_values
). The new primary key value as per default is returned (pk_new
).Call:
SQL Fiddle.
Use
regclass
as input parameter type, so only valid table names can be used to begin with and SQL injection is ruled out. The function also fails earlier and more gracefully if you should provide an illegal table name.Use an
OUT
parameter (pk_new
) to simplify the syntax.No need to figure out the next value for the primary key manually. It is inserted automatically and returned after the fact. That's not only simpler and faster, you also avoid wasted or out-of-order sequence numbers.
Use
format()
to simplify the assembly of the dynamic query string and make it less error-prone. Note how I use positional parameters for identifiers and strings respectively.I build on your implicit assumption that allowed tables have a single primary key column of type integer with a column default. Typically
serial
columns.Key element of the function is the final
INSERT
:#=
operator in a subselect and decompose the resulting row immediately.SELECT
.RETURNING
clause.OUT
parameter directly.Since I didn't want to have to use any external functions for speed purposes, I created a solution using hstores to insert a record into a table:
It's quite a bit longer than what I had envisioned, but it works and is actually quite speedy.