Exemplo de banco de dados: https://dbfiddle.uk/sERgZPiB
Tabelas e tipos
CREATE TABLE accounts (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
login text NOT NULL,
password text NOT NULL,
email text
);
CREATE TYPE account_init AS (
login text,
password text,
email text
);
Funções auxiliares
-- random string generator
-- https://www.simononsoftware.com/random-string-in-postgresql/#combined-md5-and-sql
CREATE FUNCTION random_string(length integer)
RETURNS text
LANGUAGE SQL
AS $$
SELECT upper(
substring(
(
SELECT
string_agg(
md5(
CAST (random() AS text)
),
''
)
FROM
generate_series(
1,
CAST (CEIL(length / 32.) AS integer)
)
),
1,
length
)
);
$$;
--sequence generator
CREATE FUNCTION create_series(amount integer)
RETURNS TABLE (
index_id bigint
)
LANGUAGE SQL
AS $BODY$
SELECT
generate_series AS index_id
FROM
generate_series(1, amount)
$BODY$;
Funções de entidade
CREATE FUNCTION get_accounts(
pagination_limit bigint DEFAULT 25,
pagination_offset bigint DEFAULT 0,
account_ids bigint[] DEFAULT NULL
)
RETURNS TABLE (
id bigint,
login text,
password text,
email text
)
LANGUAGE SQL
AS $BODY$
WITH input_accounts AS (
SELECT
id,
login,
password,
email
FROM
accounts
WHERE
account_ids IS NULL OR id = ANY (account_ids)
ORDER BY
id
LIMIT pagination_limit
OFFSET pagination_offset
)
SELECT
id,
login,
password,
email
FROM
input_accounts
ORDER BY
id
$BODY$;
CREATE FUNCTION create_accounts(
account_inits account_init[]
)
RETURNS TABLE (
id bigint,
login text,
password text,
email text
)
LANGUAGE SQL
AS $BODY$
WITH new_accounts AS (
INSERT INTO accounts (
login,
password,
email
)
SELECT
login,
password,
email
FROM
unnest(account_inits)
RETURNING
id
)
SELECT
id,
login,
password,
email
FROM
get_accounts(
NULL,
NULL,
ARRAY(
SELECT
id
FROM
new_accounts
)
)
ORDER BY
id
$BODY$;
Uso
WITH account_inits AS (
SELECT
index_id,
(random_string(10)) AS login,
(random_string(50)) AS password,
NULL AS email
FROM
create_series(10)
)
SELECT
id,
login,
password,
email
FROM
create_accounts(
CAST (
(
SELECT
login,
password,
email
FROM
account_inits
) AS account_init[]
)
)
ORDER BY
id ASC
;
O código atual retorna
ERROR: subquery must return only one column
LINE 31: (
Eu tentei array_agg()
e array()
ambos retornando erros diferentes. Eu pensei em usar json
type para o argumento, mas isso irá obscurecer a assinatura da função tanto para leitura quanto para depuração, então prefiro não.
Agregue os dados de entrada em uma matriz no CTE e use essa matriz diretamente.
Exemplo on-line