从 PL/pgSQL 返回查询
Returning Query from PL/pgSQL
我有一个记录列表,其中包含每个员工的员工 ID (emp_id),以及他们经理的员工 ID (manager_id)
假设我想运行查询以获取 Sandrine (emp_id = 63679) 整个命令链的所有列(即 Sandrine、Sandrine 的老板、Sandrine 的老板的老板等) .)
我将如何编写此查询?
我在 PL/pgSQL 中尝试了以下循环:
CREATE FUNCTION getpersons() RETURNS SETOF person
LANGUAGE plpgsql AS
$$ Declare
counter INTEGER := 63679 ;
Begin
WHILE (Counter is not null) loop
RETURN QUERY EXECUTE (SELECT * FROM employees WHERE employees.emp_id = Counter);
Counter = employees.manager_id;
END LOOP;
END; $$
SELECT * from person;
数据库看起来像这样:
您的函数有几个错误。
- 您 select 来自名为
employees
的 table,因此函数应该 return setof employees
,而不是 "person"
- 你没有在任何地方存储 select 的结果,所以你不能实际分配 "counter" 变量(这对于变量名来说是一个非常糟糕的选择)
execute
只有动态 SQL 才需要,如果你有静态 SQL 则不需要
- 您应该将员工 ID 作为参数传递,而不是对其进行硬编码。
因此,为了实际使用您检索到的行,您需要将其存储在一个变量中,该变量可以定义为与结果 table 相同的类型。
将所有这些放在一起,您的函数应该如下所示:
CREATE FUNCTION getpersons(p_startid integer)
RETURNS SETOF employee
LANGUAGE plpgsql AS
$$ Declare
l_id INTEGER := p_startid;
l_row employee;
Begin
WHILE (l_id is not null) loop
SELECT *
into l_row
FROM employee
WHERE emp_id = l_id;
l_id := l_row.manager_id;
return next l_row;
END LOOP;
END;
$$
;
那么你可以这样使用它:
select *
from getpersons(63679);
但是,遍历这样的层级并不需要编写函数。这可以通过使用 recursive common table expression
的单个 SQL 语句来完成
with recursive persons as (
select *
from employees
where id = 63679
union all
select ch.*
from employees ch
join persons p on p.manager_id = ch.id
)
select *
from persons;
我有一个记录列表,其中包含每个员工的员工 ID (emp_id),以及他们经理的员工 ID (manager_id)
假设我想运行查询以获取 Sandrine (emp_id = 63679) 整个命令链的所有列(即 Sandrine、Sandrine 的老板、Sandrine 的老板的老板等) .)
我将如何编写此查询?
我在 PL/pgSQL 中尝试了以下循环:
CREATE FUNCTION getpersons() RETURNS SETOF person
LANGUAGE plpgsql AS
$$ Declare
counter INTEGER := 63679 ;
Begin
WHILE (Counter is not null) loop
RETURN QUERY EXECUTE (SELECT * FROM employees WHERE employees.emp_id = Counter);
Counter = employees.manager_id;
END LOOP;
END; $$
SELECT * from person;
数据库看起来像这样:
您的函数有几个错误。
- 您 select 来自名为
employees
的 table,因此函数应该 returnsetof employees
,而不是 "person" - 你没有在任何地方存储 select 的结果,所以你不能实际分配 "counter" 变量(这对于变量名来说是一个非常糟糕的选择)
execute
只有动态 SQL 才需要,如果你有静态 SQL 则不需要
- 您应该将员工 ID 作为参数传递,而不是对其进行硬编码。
因此,为了实际使用您检索到的行,您需要将其存储在一个变量中,该变量可以定义为与结果 table 相同的类型。
将所有这些放在一起,您的函数应该如下所示:
CREATE FUNCTION getpersons(p_startid integer)
RETURNS SETOF employee
LANGUAGE plpgsql AS
$$ Declare
l_id INTEGER := p_startid;
l_row employee;
Begin
WHILE (l_id is not null) loop
SELECT *
into l_row
FROM employee
WHERE emp_id = l_id;
l_id := l_row.manager_id;
return next l_row;
END LOOP;
END;
$$
;
那么你可以这样使用它:
select *
from getpersons(63679);
但是,遍历这样的层级并不需要编写函数。这可以通过使用 recursive common table expression
的单个 SQL 语句来完成with recursive persons as (
select *
from employees
where id = 63679
union all
select ch.*
from employees ch
join persons p on p.manager_id = ch.id
)
select *
from persons;