With modern day PostgreSQL you can simplify such a function.
Test setup:
CREATE TABLE tbl1 (id int, value text);
No need to create a type explicitly in this case (if the type is based on a table row), it is created for every table implicitly.
Function:
CREATE FUNCTION f_insert_rows_into_tbl1(tbl1[])
RETURNS void
LANGUAGE sql AS
$func$
INSERT INTO tbl1 -- rare case where it's safe to omit target columns
SELECT *
FROM unnest($1) sub;
$func$;
Since the composite row type is the only column in the subquery, it will be decomposed in the outer SELECT
automatically.
Since the input type is defined by the table row, this is one of the rare cases where it's safe to omit target columns for the INSERT
command. In fact, it may even be advisable - to stay in sync with possible future changes to the table definition.
Call:
SELECT f_insert_rows_into_tbl1('{"(1,foo)","(2,bar)"}');
Note the input syntax for an array of rows! If you are uncertain about the correct syntax, see: