数据库示例:https ://dbfiddle.uk/sERgZPiB
表格和类型
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
);
辅助函数
-- 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$;
实体函数
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$;
用法
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
;
当前代码返回
ERROR: subquery must return only one column
LINE 31: (
我试过了array_agg()
,array()
他们都返回了不同的错误。我考虑过使用json
类型作为参数,但这会掩盖读取和调试的函数签名,所以我宁愿不这样做。
将输入数据聚合到 CTE 中的一个数组中,然后直接使用该数组。
在线示例