Function inserting multiple rows in a table












0















So I have the following 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


I've created the following function:



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 is a type of output I created:



CREATE TYPE test2 AS(
id smallint,
year smallint,
total_albums integer)


The function accepts a year and type of perfomer. It returns, for every year and performer (in this case Guitarist, 'G'), the amount of records a performer has participated in every year.



What I would like is for the function to insert that output into a table I've created, instead of just showing the output:



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









share|improve this question

























  • "insert that output into a table I've created", you haven't shown us the table, instead you reposted the type definition. Then do you want it to to both write that output to the table and return it, or just write it?

    – 404
    Nov 24 '18 at 14:15











  • Sorry, that was a mistake, I've corrected it now. The table is empty, ideally it would return the type and insert it in the table TEST2_TABLE. However, if that's not possible I'd settle for just the function filling the table

    – Sergio
    Nov 24 '18 at 15:03
















0















So I have the following 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


I've created the following function:



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 is a type of output I created:



CREATE TYPE test2 AS(
id smallint,
year smallint,
total_albums integer)


The function accepts a year and type of perfomer. It returns, for every year and performer (in this case Guitarist, 'G'), the amount of records a performer has participated in every year.



What I would like is for the function to insert that output into a table I've created, instead of just showing the output:



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









share|improve this question

























  • "insert that output into a table I've created", you haven't shown us the table, instead you reposted the type definition. Then do you want it to to both write that output to the table and return it, or just write it?

    – 404
    Nov 24 '18 at 14:15











  • Sorry, that was a mistake, I've corrected it now. The table is empty, ideally it would return the type and insert it in the table TEST2_TABLE. However, if that's not possible I'd settle for just the function filling the table

    – Sergio
    Nov 24 '18 at 15:03














0












0








0








So I have the following 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


I've created the following function:



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 is a type of output I created:



CREATE TYPE test2 AS(
id smallint,
year smallint,
total_albums integer)


The function accepts a year and type of perfomer. It returns, for every year and performer (in this case Guitarist, 'G'), the amount of records a performer has participated in every year.



What I would like is for the function to insert that output into a table I've created, instead of just showing the output:



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









share|improve this question
















So I have the following 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


I've created the following function:



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 is a type of output I created:



CREATE TYPE test2 AS(
id smallint,
year smallint,
total_albums integer)


The function accepts a year and type of perfomer. It returns, for every year and performer (in this case Guitarist, 'G'), the amount of records a performer has participated in every year.



What I would like is for the function to insert that output into a table I've created, instead of just showing the output:



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






postgresql postgresql-9.1 postgresql-9.2 postgresql-9.5






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 15:02







Sergio

















asked Nov 24 '18 at 13:13









SergioSergio

214




214













  • "insert that output into a table I've created", you haven't shown us the table, instead you reposted the type definition. Then do you want it to to both write that output to the table and return it, or just write it?

    – 404
    Nov 24 '18 at 14:15











  • Sorry, that was a mistake, I've corrected it now. The table is empty, ideally it would return the type and insert it in the table TEST2_TABLE. However, if that's not possible I'd settle for just the function filling the table

    – Sergio
    Nov 24 '18 at 15:03



















  • "insert that output into a table I've created", you haven't shown us the table, instead you reposted the type definition. Then do you want it to to both write that output to the table and return it, or just write it?

    – 404
    Nov 24 '18 at 14:15











  • Sorry, that was a mistake, I've corrected it now. The table is empty, ideally it would return the type and insert it in the table TEST2_TABLE. However, if that's not possible I'd settle for just the function filling the table

    – Sergio
    Nov 24 '18 at 15:03

















"insert that output into a table I've created", you haven't shown us the table, instead you reposted the type definition. Then do you want it to to both write that output to the table and return it, or just write it?

– 404
Nov 24 '18 at 14:15





"insert that output into a table I've created", you haven't shown us the table, instead you reposted the type definition. Then do you want it to to both write that output to the table and return it, or just write it?

– 404
Nov 24 '18 at 14:15













Sorry, that was a mistake, I've corrected it now. The table is empty, ideally it would return the type and insert it in the table TEST2_TABLE. However, if that's not possible I'd settle for just the function filling the table

– Sergio
Nov 24 '18 at 15:03





Sorry, that was a mistake, I've corrected it now. The table is empty, ideally it would return the type and insert it in the table TEST2_TABLE. However, if that's not possible I'd settle for just the function filling the table

– Sergio
Nov 24 '18 at 15:03












1 Answer
1






active

oldest

votes


















1














Here's the function:



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;


So the signature and output is the same as your original function. Main differences are:




  • No need to use a loop and read/return one row at a time. You can return the result of your query directly. Much faster like that.

  • To accomplish both inserting into a table and returning the same results, it uses a CTE which inserts the data in the table and returns everything that was inserted, then selects from that CTE as the return output.


I've also removed the aliases. Any identifier in postgres is lowercase, unless in double quotes. Since G and C were not in quotes, the table names are actually g and c, respectively. So I just used the actual lowercase table names.






share|improve this answer
























  • thanks for your help, it works great!

    – Sergio
    Nov 24 '18 at 15:42











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53458510%2ffunction-inserting-multiple-rows-in-a-table%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Here's the function:



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;


So the signature and output is the same as your original function. Main differences are:




  • No need to use a loop and read/return one row at a time. You can return the result of your query directly. Much faster like that.

  • To accomplish both inserting into a table and returning the same results, it uses a CTE which inserts the data in the table and returns everything that was inserted, then selects from that CTE as the return output.


I've also removed the aliases. Any identifier in postgres is lowercase, unless in double quotes. Since G and C were not in quotes, the table names are actually g and c, respectively. So I just used the actual lowercase table names.






share|improve this answer
























  • thanks for your help, it works great!

    – Sergio
    Nov 24 '18 at 15:42
















1














Here's the function:



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;


So the signature and output is the same as your original function. Main differences are:




  • No need to use a loop and read/return one row at a time. You can return the result of your query directly. Much faster like that.

  • To accomplish both inserting into a table and returning the same results, it uses a CTE which inserts the data in the table and returns everything that was inserted, then selects from that CTE as the return output.


I've also removed the aliases. Any identifier in postgres is lowercase, unless in double quotes. Since G and C were not in quotes, the table names are actually g and c, respectively. So I just used the actual lowercase table names.






share|improve this answer
























  • thanks for your help, it works great!

    – Sergio
    Nov 24 '18 at 15:42














1












1








1







Here's the function:



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;


So the signature and output is the same as your original function. Main differences are:




  • No need to use a loop and read/return one row at a time. You can return the result of your query directly. Much faster like that.

  • To accomplish both inserting into a table and returning the same results, it uses a CTE which inserts the data in the table and returns everything that was inserted, then selects from that CTE as the return output.


I've also removed the aliases. Any identifier in postgres is lowercase, unless in double quotes. Since G and C were not in quotes, the table names are actually g and c, respectively. So I just used the actual lowercase table names.






share|improve this answer













Here's the function:



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;


So the signature and output is the same as your original function. Main differences are:




  • No need to use a loop and read/return one row at a time. You can return the result of your query directly. Much faster like that.

  • To accomplish both inserting into a table and returning the same results, it uses a CTE which inserts the data in the table and returns everything that was inserted, then selects from that CTE as the return output.


I've also removed the aliases. Any identifier in postgres is lowercase, unless in double quotes. Since G and C were not in quotes, the table names are actually g and c, respectively. So I just used the actual lowercase table names.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 24 '18 at 15:21









404404

3,1401726




3,1401726













  • thanks for your help, it works great!

    – Sergio
    Nov 24 '18 at 15:42



















  • thanks for your help, it works great!

    – Sergio
    Nov 24 '18 at 15:42

















thanks for your help, it works great!

– Sergio
Nov 24 '18 at 15:42





thanks for your help, it works great!

– Sergio
Nov 24 '18 at 15:42




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53458510%2ffunction-inserting-multiple-rows-in-a-table%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Wiesbaden

Marschland

Dieringhausen