Функция вставки нескольких строк в таблицу - PullRequest
0 голосов
/ 24 ноября 2018

Итак, у меня есть следующие таблицы.

             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)

Функция принимает год и тип перфомера.Он возвращает для каждого года и исполнителя (в данном случае гитариста 'G') количество записей, в которых исполнитель участвовал каждый год.

Мне бы хотелось, чтобы функция вставляла этот вывод втаблицу, которую я создал, вместо того, чтобы просто показать вывод:

CREATE TABLE TEST2_TABLE (
id smallint,
year smallint,
total_albums integer );

1 Ответ

0 голосов
/ 24 ноября 2018

Вот функция:

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;

Таким образом, подпись и вывод такие же, как и у исходной функции.Основные отличия:

  • Нет необходимости использовать цикл и читать / возвращать по одной строке за раз.Вы можете вернуть результат вашего запроса напрямую.Гораздо быстрее, как это.
  • Чтобы выполнить вставку в таблицу и возвращать одинаковые результаты, он использует CTE, который вставляет данные в таблицу и возвращает все, что было вставлено, а затем выбирает из этого CTE в качестве возвратавывод.

Я также удалил псевдонимы.Любой идентификатор в postgres должен быть строчным, кроме двойных кавычек.Поскольку G и C не были в кавычках, имена таблиц на самом деле g и c соответственно.Поэтому я просто использовал настоящие имена таблиц в нижнем регистре.

...