【发布时间】:2019-05-01 20:16:05
【问题描述】:
我很难理解何时使用 PL/pgSQL FOR 循环与常规 SQL。
这个问题绝对是在显示我的幼稚,但这是我感到困惑的地方:
给定这张表:
CREATE TABLE bins AS
SELECT * FROM GENERATE_SERIES(1, 10) AS id;
如果我想在每一行的 id 字段中加 1,我会这样做:
select id+1 from bins;
会正确返回
2
3
4
5
6
7
8
9
10
11
现在,如果我为此操作使用 PL/pgSQL 函数,它看起来像这样:
CREATE OR REPLACE FUNCTION add_one(
n integer
)
RETURNS VOID AS $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN SELECT id
FROM bins
LOOP
RAISE NOTICE '%', rec.id+n;
END LOOP;
END;
$$ LANGUAGE plpgsql;
那么
select add_one(1)
会产生
-- Executing query:
select add_one(1)
NOTICE: 2
CONTEXT: PL/pgSQL function add_one(integer) line 9 at RAISE
NOTICE: 3
CONTEXT: PL/pgSQL function add_one(integer) line 9 at RAISE
NOTICE: 4
CONTEXT: PL/pgSQL function add_one(integer) line 9 at RAISE
NOTICE: 5
CONTEXT: PL/pgSQL function add_one(integer) line 9 at RAISE
NOTICE: 6
CONTEXT: PL/pgSQL function add_one(integer) line 9 at RAISE
NOTICE: 7
CONTEXT: PL/pgSQL function add_one(integer) line 9 at RAISE
NOTICE: 8
CONTEXT: PL/pgSQL function add_one(integer) line 9 at RAISE
NOTICE: 9
CONTEXT: PL/pgSQL function add_one(integer) line 9 at RAISE
NOTICE: 10
CONTEXT: PL/pgSQL function add_one(integer) line 9 at RAISE
NOTICE: 11
CONTEXT: PL/pgSQL function add_one(integer) line 9 at RAISE
所以我的问题是,SQL select 语句在某种程度上就像一个 for 循环,因为在这个例子中,它为每一行添加一个 1……这与 PL/pgSQL 函数中发生的事情相同。这是一个准确的描述吗?
【问题讨论】:
-
您的最终比较是准确的。这也有点无意义。斧头能劈木头,炸弹也能劈。这告诉我们什么?真的没什么。简单的
SELECT比在 plpgsql 中循环更快、更简单、更短且更不容易出错。就是这样。 -
与其指出循环和SQL语句可以用来做一些相同的事情,更重要的是要注意它们可以用来做不同的事情。例如,如果您需要构建和执行一系列 SQL 语句,这些语句的选择标准(将在 WHERE 子句中使用)存储在表的行中,那么循环遍历表的行将很有用,而没有一个SQL 语句将创建并执行整个 SQL 语句系列。
标签: sql postgresql plpgsql