Returning multiple result sets from postgres: refcursors, functions or new features?
Premise:
An entity has many children and grandchildren (gists, versions and files respectively, in this instance). When it (gist) is requested, we want its children (versions) and grandchildren (files for versions) as well. Here I am really pushing to do as much in SQL as possible, instead of composing several queries together and munging them together in a scripting language. Can it be done? Does the tooling that supports sending queries to a PostgresQL db support the results returned?
Prior art:
- PostgreSQL function returning multiple result sets
- http://www.sqlines.com/postgresql/how-to/return_result_set_from_stored_procedure
- https://www.postgresql.org/docs/10/plpgsql-overview.html
Schema:
Schema (and SQL to insert mock data)
My attempt via stored function (Note, I have simplified to just parent/child return sets, skipping grandchild for now):
CREATE OR REPLACE FUNCTION get_gist_with_children(gist_ref refcursor,
version_ref refcursor, gist_id_in UUID)
RETURNS SETOF refcursor AS $$
BEGIN
OPEN gist_ref FOR SELECT * from gist where gist_id = gist_id_in;
RETURN NEXT gist_ref;
OPEN version_ref FOR SELECT * from version where gist_id = gist_id_in;
RETURN NEXT version_ref;
END;
$$ LANGUAGE plpgsql;
The query to access that function:
BEGIN;
SELECT get_gist_with_children('gist_ref', 'version_ref', <replace with known UUID of gist record>);
FETCH ALL IN "gist_ref";
FETCH ALL IN "version_ref";
COMMIT;
returns in POSTICO
Postico, a PostgresQL GUI, just returns the refcursor symbol strings in two rows.
returns in psql
psql returns the first set of results and then... hangs?
note: I can successfully query both tables on that gist_id and records returned in separate queries.
Are there new features of Postgres that could achieve this outcome? Is there a better way to use cursors to do so? Is the real problem that the tooling (psql, Postico) does not handle the returning of multiple data sets? Curious about ways forward beyond just falling back on composition via scripting languages.
sql postgresql
add a comment |
Premise:
An entity has many children and grandchildren (gists, versions and files respectively, in this instance). When it (gist) is requested, we want its children (versions) and grandchildren (files for versions) as well. Here I am really pushing to do as much in SQL as possible, instead of composing several queries together and munging them together in a scripting language. Can it be done? Does the tooling that supports sending queries to a PostgresQL db support the results returned?
Prior art:
- PostgreSQL function returning multiple result sets
- http://www.sqlines.com/postgresql/how-to/return_result_set_from_stored_procedure
- https://www.postgresql.org/docs/10/plpgsql-overview.html
Schema:
Schema (and SQL to insert mock data)
My attempt via stored function (Note, I have simplified to just parent/child return sets, skipping grandchild for now):
CREATE OR REPLACE FUNCTION get_gist_with_children(gist_ref refcursor,
version_ref refcursor, gist_id_in UUID)
RETURNS SETOF refcursor AS $$
BEGIN
OPEN gist_ref FOR SELECT * from gist where gist_id = gist_id_in;
RETURN NEXT gist_ref;
OPEN version_ref FOR SELECT * from version where gist_id = gist_id_in;
RETURN NEXT version_ref;
END;
$$ LANGUAGE plpgsql;
The query to access that function:
BEGIN;
SELECT get_gist_with_children('gist_ref', 'version_ref', <replace with known UUID of gist record>);
FETCH ALL IN "gist_ref";
FETCH ALL IN "version_ref";
COMMIT;
returns in POSTICO
Postico, a PostgresQL GUI, just returns the refcursor symbol strings in two rows.
returns in psql
psql returns the first set of results and then... hangs?
note: I can successfully query both tables on that gist_id and records returned in separate queries.
Are there new features of Postgres that could achieve this outcome? Is there a better way to use cursors to do so? Is the real problem that the tooling (psql, Postico) does not handle the returning of multiple data sets? Curious about ways forward beyond just falling back on composition via scripting languages.
sql postgresql
add a comment |
Premise:
An entity has many children and grandchildren (gists, versions and files respectively, in this instance). When it (gist) is requested, we want its children (versions) and grandchildren (files for versions) as well. Here I am really pushing to do as much in SQL as possible, instead of composing several queries together and munging them together in a scripting language. Can it be done? Does the tooling that supports sending queries to a PostgresQL db support the results returned?
Prior art:
- PostgreSQL function returning multiple result sets
- http://www.sqlines.com/postgresql/how-to/return_result_set_from_stored_procedure
- https://www.postgresql.org/docs/10/plpgsql-overview.html
Schema:
Schema (and SQL to insert mock data)
My attempt via stored function (Note, I have simplified to just parent/child return sets, skipping grandchild for now):
CREATE OR REPLACE FUNCTION get_gist_with_children(gist_ref refcursor,
version_ref refcursor, gist_id_in UUID)
RETURNS SETOF refcursor AS $$
BEGIN
OPEN gist_ref FOR SELECT * from gist where gist_id = gist_id_in;
RETURN NEXT gist_ref;
OPEN version_ref FOR SELECT * from version where gist_id = gist_id_in;
RETURN NEXT version_ref;
END;
$$ LANGUAGE plpgsql;
The query to access that function:
BEGIN;
SELECT get_gist_with_children('gist_ref', 'version_ref', <replace with known UUID of gist record>);
FETCH ALL IN "gist_ref";
FETCH ALL IN "version_ref";
COMMIT;
returns in POSTICO
Postico, a PostgresQL GUI, just returns the refcursor symbol strings in two rows.
returns in psql
psql returns the first set of results and then... hangs?
note: I can successfully query both tables on that gist_id and records returned in separate queries.
Are there new features of Postgres that could achieve this outcome? Is there a better way to use cursors to do so? Is the real problem that the tooling (psql, Postico) does not handle the returning of multiple data sets? Curious about ways forward beyond just falling back on composition via scripting languages.
sql postgresql
Premise:
An entity has many children and grandchildren (gists, versions and files respectively, in this instance). When it (gist) is requested, we want its children (versions) and grandchildren (files for versions) as well. Here I am really pushing to do as much in SQL as possible, instead of composing several queries together and munging them together in a scripting language. Can it be done? Does the tooling that supports sending queries to a PostgresQL db support the results returned?
Prior art:
- PostgreSQL function returning multiple result sets
- http://www.sqlines.com/postgresql/how-to/return_result_set_from_stored_procedure
- https://www.postgresql.org/docs/10/plpgsql-overview.html
Schema:
Schema (and SQL to insert mock data)
My attempt via stored function (Note, I have simplified to just parent/child return sets, skipping grandchild for now):
CREATE OR REPLACE FUNCTION get_gist_with_children(gist_ref refcursor,
version_ref refcursor, gist_id_in UUID)
RETURNS SETOF refcursor AS $$
BEGIN
OPEN gist_ref FOR SELECT * from gist where gist_id = gist_id_in;
RETURN NEXT gist_ref;
OPEN version_ref FOR SELECT * from version where gist_id = gist_id_in;
RETURN NEXT version_ref;
END;
$$ LANGUAGE plpgsql;
The query to access that function:
BEGIN;
SELECT get_gist_with_children('gist_ref', 'version_ref', <replace with known UUID of gist record>);
FETCH ALL IN "gist_ref";
FETCH ALL IN "version_ref";
COMMIT;
returns in POSTICO
Postico, a PostgresQL GUI, just returns the refcursor symbol strings in two rows.
returns in psql
psql returns the first set of results and then... hangs?
note: I can successfully query both tables on that gist_id and records returned in separate queries.
Are there new features of Postgres that could achieve this outcome? Is there a better way to use cursors to do so? Is the real problem that the tooling (psql, Postico) does not handle the returning of multiple data sets? Curious about ways forward beyond just falling back on composition via scripting languages.
sql postgresql
sql postgresql
asked Nov 22 '18 at 19:33
Underwater_developerUnderwater_developer
186111
186111
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
The PostgreSQL database engine is perfectly capable of handling multiple open result sets per connections, even per call. It can keep multiple cursors that are returned from a single call using multiple "result set"s.
Don't be afraid of using them. Just try multiple SELECT
s inside your procedure and perform a SINGLE call. Then, it's easy to verify you can get read from all the result sets, even in parallel.
If you asked this same question on MySQL, then answer would categorically a "No". MySQL is far more limited. But with PostgreSQL this is perfectly possible.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53437137%2freturning-multiple-result-sets-from-postgres-refcursors-functions-or-new-featu%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
The PostgreSQL database engine is perfectly capable of handling multiple open result sets per connections, even per call. It can keep multiple cursors that are returned from a single call using multiple "result set"s.
Don't be afraid of using them. Just try multiple SELECT
s inside your procedure and perform a SINGLE call. Then, it's easy to verify you can get read from all the result sets, even in parallel.
If you asked this same question on MySQL, then answer would categorically a "No". MySQL is far more limited. But with PostgreSQL this is perfectly possible.
add a comment |
The PostgreSQL database engine is perfectly capable of handling multiple open result sets per connections, even per call. It can keep multiple cursors that are returned from a single call using multiple "result set"s.
Don't be afraid of using them. Just try multiple SELECT
s inside your procedure and perform a SINGLE call. Then, it's easy to verify you can get read from all the result sets, even in parallel.
If you asked this same question on MySQL, then answer would categorically a "No". MySQL is far more limited. But with PostgreSQL this is perfectly possible.
add a comment |
The PostgreSQL database engine is perfectly capable of handling multiple open result sets per connections, even per call. It can keep multiple cursors that are returned from a single call using multiple "result set"s.
Don't be afraid of using them. Just try multiple SELECT
s inside your procedure and perform a SINGLE call. Then, it's easy to verify you can get read from all the result sets, even in parallel.
If you asked this same question on MySQL, then answer would categorically a "No". MySQL is far more limited. But with PostgreSQL this is perfectly possible.
The PostgreSQL database engine is perfectly capable of handling multiple open result sets per connections, even per call. It can keep multiple cursors that are returned from a single call using multiple "result set"s.
Don't be afraid of using them. Just try multiple SELECT
s inside your procedure and perform a SINGLE call. Then, it's easy to verify you can get read from all the result sets, even in parallel.
If you asked this same question on MySQL, then answer would categorically a "No". MySQL is far more limited. But with PostgreSQL this is perfectly possible.
answered Dec 28 '18 at 0:49
The ImpalerThe Impaler
10.5k41341
10.5k41341
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53437137%2freturning-multiple-result-sets-from-postgres-refcursors-functions-or-new-featu%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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