There is nothing wrong with a PL/pgSQL function, but for "a call once in a while" and only plain SQL statements, LANGUAGE sql
is the more appropriate format. Detailed discussion when to use either:
CREATE OR REPLACE FUNCTION my_insert()
RETURNS void AS
$func$
WITH sel AS (SELECT one_col, another_col FROM another_table WHERE <some_condition>)
, ins1 AS (INSERT INTO dummy (col1,col2) SELECT 'aa', one_col FROM sel)
INSERT INTO dummy (col1,col2) SELECT 'bb', another_col FROM sel;
$func$ LANGUAGE sql
The CTEs can be a bit more expensive due to materializing the set from the first SELECT
- or not, if that actually saves selecting the rows multiple times, like separate INSERT
statements would.
You probably want all your INSERT
statements in the same batch to be based off the same snapshot. In case there can be concurrent write operation, the CTEs would guarantee that, because the whole query is based on the same snapshot of all involved tables.
If concurrency is not a problem and the SELECT
is cheap (or not the same), simple, separate INSERTs may be faster.