在 table 中插入多行的函数
Function inserting multiple rows in a table
所以我有以下 tables.
G
__________________________
id_musician | id_album
--------------------------
1 | 51
3 | 52
2 | 53
3 | 54
1 | 55
3 | 56
C
__________________________
id_album | year
--------------------------
51 | 1990
52 | 2001
53 | 1990
54 | 2001
55 | 1945
56 | 1945
我创建了以下函数:
CREATE OR REPLACE FUNCTION test2 (year1 INTEGER, p_type VARCHAR(1))
RETURNS SETOF test2 AS $$
DECLARE
output test2;
BEGIN
IF p_type='S' THEN
FOR output IN SELECT g.id_artist, c.year, COUNT(c.id_album) AS albums
FROM G g, C c
WHERE g.id_album = c.id_album AND
c.year = year1
GROUP BY c.year, g.id_musician
LOOP
RETURN NEXT output;
END LOOP;
END IF
RETURN;
END;
$$LANGUAGE plpgsql;
test2 是我创建的一种输出:
CREATE TYPE test2 AS(
id smallint,
year smallint,
total_albums integer)
该函数接受表演者的年份和类型。它returns,对于每年和表演者(在本例中为吉他手,'G'),表演者每年参与的记录数量。
我想要的是将输出插入到我创建的 table 中的函数,而不是仅仅显示输出:
CREATE TABLE TEST2_TABLE (
id smallint,
year smallint,
total_albums integer );
函数如下:
CREATE OR REPLACE FUNCTION test2 (year1 INTEGER, p_type VARCHAR(1))
RETURNS SETOF test2 AS
$BODY$
BEGIN
IF p_type='S' THEN
RETURN QUERY (
WITH inserted AS (
INSERT INTO test2_table
SELECT g.id_musician, c.year, COUNT(c.id_album)::INTEGER AS albums
FROM g, c
WHERE g.id_album = c.id_album
AND c.year = year1
GROUP BY c.year, g.id_musician
RETURNING *
)
SELECT *
FROM inserted
);
ELSE
RETURN;
END IF;
END
$BODY$
LANGUAGE plpgsql;
因此签名和输出与您的原始函数相同。主要区别是:
- 无需使用循环,read/return 一次一行。您可以直接 return 查询结果。这样快多了。
- 为了在 table 和 return 中插入相同的结果,它使用 CTE 将数据插入 table 和 return 中的所有内容已插入,然后从该 CTE 中选择作为 return 输出。
我也删除了别名。 postgres 中的任何标识符都是小写的,除非在双引号中。由于 G
和 C
不在引号中,因此 table 名称实际上分别是 g
和 c
。所以我只使用了实际的小写 table 名称。
所以我有以下 tables.
G
__________________________
id_musician | id_album
--------------------------
1 | 51
3 | 52
2 | 53
3 | 54
1 | 55
3 | 56
C
__________________________
id_album | year
--------------------------
51 | 1990
52 | 2001
53 | 1990
54 | 2001
55 | 1945
56 | 1945
我创建了以下函数:
CREATE OR REPLACE FUNCTION test2 (year1 INTEGER, p_type VARCHAR(1))
RETURNS SETOF test2 AS $$
DECLARE
output test2;
BEGIN
IF p_type='S' THEN
FOR output IN SELECT g.id_artist, c.year, COUNT(c.id_album) AS albums
FROM G g, C c
WHERE g.id_album = c.id_album AND
c.year = year1
GROUP BY c.year, g.id_musician
LOOP
RETURN NEXT output;
END LOOP;
END IF
RETURN;
END;
$$LANGUAGE plpgsql;
test2 是我创建的一种输出:
CREATE TYPE test2 AS(
id smallint,
year smallint,
total_albums integer)
该函数接受表演者的年份和类型。它returns,对于每年和表演者(在本例中为吉他手,'G'),表演者每年参与的记录数量。
我想要的是将输出插入到我创建的 table 中的函数,而不是仅仅显示输出:
CREATE TABLE TEST2_TABLE (
id smallint,
year smallint,
total_albums integer );
函数如下:
CREATE OR REPLACE FUNCTION test2 (year1 INTEGER, p_type VARCHAR(1))
RETURNS SETOF test2 AS
$BODY$
BEGIN
IF p_type='S' THEN
RETURN QUERY (
WITH inserted AS (
INSERT INTO test2_table
SELECT g.id_musician, c.year, COUNT(c.id_album)::INTEGER AS albums
FROM g, c
WHERE g.id_album = c.id_album
AND c.year = year1
GROUP BY c.year, g.id_musician
RETURNING *
)
SELECT *
FROM inserted
);
ELSE
RETURN;
END IF;
END
$BODY$
LANGUAGE plpgsql;
因此签名和输出与您的原始函数相同。主要区别是:
- 无需使用循环,read/return 一次一行。您可以直接 return 查询结果。这样快多了。
- 为了在 table 和 return 中插入相同的结果,它使用 CTE 将数据插入 table 和 return 中的所有内容已插入,然后从该 CTE 中选择作为 return 输出。
我也删除了别名。 postgres 中的任何标识符都是小写的,除非在双引号中。由于 G
和 C
不在引号中,因此 table 名称实际上分别是 g
和 c
。所以我只使用了实际的小写 table 名称。