存储过程的新功能,需要在存储过程中执行多个查询并返回结果。我想知道这是否可能。
Ex: 查询1返回用户标识列表.. 从user =?
的用户中选择userid对于上述查询中的每个用户标识,我需要执行三个不同的查询,例如 查询2从sessionid中选择session_details,其中userid =? 查询3从userid =?
的位置选择位置返回值应该是session_details和location的集合。
这可能,你能提供一些提示吗?
答案 0 :(得分:0)
完全基于您的示例,这可能是最简单的方法:
CREATE FUNCTION my_func(user_id INTEGER)
RETURNS TABLE (userid INTEGER, session INTEGER, location TEXT) AS
$$
SELECT u.userid, s.session, l.location
FROM -- etc... your query here
$$
LANGUAGE SQL STABLE;
发表评论: 这是一个不同的问题。一个问题是如何在存储过程中返回包含多个字段的多个记录。一种方法如上。
另一个问题是如何编写从多个表中获取数据的查询。同样,有很多方法可以做到这一点。一种方法是(再次,基于我对示例中的要求的解释):
SELECT userid
, ARRAY_AGG(SELECT session_details FROM session s WHERE s.userid = u.userid)
, ARRAY_AGG(SELECT l.location FROM location l WHERE l.userid = u.userid)
FROM user u
WHERE username = user_name
这将返回一条记录,其中包含user_id,该用户的session_details数组以及该用户的位置数组。
然后该功能可以更改为:
CREATE FUNCTION my_func(user_name TEXT, OUT userid INTEGER, OUT session_details TEXT[], OUT locations TEXT[])
AS $$
SELECT userid
, ARRAY(SELECT session_details FROM session s WHERE s.userid = u.userid)
, ARRAY(SELECT l.location FROM location l WHERE l.userid = u.userid)
FROM user u
WHERE username = user_name;
$$ LANGUAGE SQL STABLE;
答案 1 :(得分:0)
您可以像这样遍历查询结果:
FOR id IN Select userid from user where username = ?
LOOP
...
END LOOP;
答案 2 :(得分:0)
正如@Fahad Anjum在评论中所说,如果你能在查询中做到这一点,那就更好了。但如果这不可行,那么你就有了树的可能性来实现你想要的东西。
<强> 1。 SETOF 强>
您可以返回一组值。该集可以是现有表,时态表或您定义的TYPE。
TYPE示例:
-- In your case the type could be (userid integer, session integer, location text)
CREATE TYPE tester AS (id integer);
-- The pl returns a SETOF the created type.
CREATE OR REPLACE FUNCTION test() RETURNS SETOF tester
AS $$
BEGIN
RETURN QUERY SELECT generate_series(1, 3) as id;
END;
$$ LANGUAGE plpgsql
-- Then, you get the set by selecting the PL as if it were a table.
SELECT * FROM test();
表格和临时表格示例:
-- Create a temporal table o a regular table:
CREATE TEMP TABLE test_table(id integer);
-- or CREATE TABLE test_table(id integer);
-- or use an existing table in your schema(s);
-- The pl returns a SETOF the table you need
CREATE OR REPLACE FUNCTION test() RETURNS SETOF test_table
AS $$
BEGIN
RETURN QUERY SELECT generate_series(1, 3) as id;
END;
$$ LANGUAGE plpgsql
-- Then, you get the set by selecting the PL as if it were a table.
SELECT * FROM test();
-- NOTE: Since you are only returning a SETOF the table,
-- you don't insert any data into the table.
-- So, if you select the 'temp' table you won't see any changes.
SELECT * FROM test_table
<强> 2。表强>
PL可以返回一个表,它类似于创建一个临时表,然后返回一个SETOF,但是,在这种情况下,你声明de&#39; temp&#39;关于&#39;表的回复&#39; PL的句子。
-- Next to TABLE you define the columns of the table the PL will return
CREATE OR REPLACE FUNCTION test() RETURNS TABLE (id integer)
AS $$
BEGIN
RETURN QUERY SELECT generate_series(1, 3) as id;
END;
$$ LANGUAGE plpgsql
-- As the other examples, you select the PL to get the data.
SELECT * FROM test();
第3。 REFCURSOR 强>
这是更复杂的解决方案。您返回游标,而不是实际数据。如果你需要动态的&#39;返回集合的值,这是解决方案。
但由于您需要静态数据,因此您不需要此选项。
使用任何这些方式取决于任何特定情况,如果您经常使用不同方式的用户ID,会话,位置和PL,最好使用带有类型的SETOF。
如果您的表具有userid,session,location列,则最好返回SETOF表。
如果你只使用一个案例的用户ID,会话,位置,那么最好使用&#39; RETURNS TABLE&#39;方法
如果您需要返回一个动态集,则必须使用游标......但该解决方案确实更先进。