Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 循环中的游标vs select语句_Postgresql_Plpgsql - Fatal编程技术网

Postgresql 循环中的游标vs select语句

Postgresql 循环中的游标vs select语句,postgresql,plpgsql,Postgresql,Plpgsql,我刚才在另一个StackOverflow问题中看到了一个简单的例子,它使用游标在表中循环。我只需循环遍历select查询的结果,而不是将select查询包装在光标中。使用光标的优点是什么 (我不能在这里包括这个例子,因为StackOverflow认为我的问题主要是代码,需要更多的细节。我以前遇到过这种恼人的限制。如果我能用几句话清楚地问我的问题,我应该可以。我会看看是否能找到指向该问题的链接,如果可以,我会在这里添加链接。) 这是我看到光标使用的地方 使用光标的优点是什么 唯一的优点是你必须编写

我刚才在另一个StackOverflow问题中看到了一个简单的例子,它使用游标在表中循环。我只需循环遍历select查询的结果,而不是将select查询包装在光标中。使用光标的优点是什么

(我不能在这里包括这个例子,因为StackOverflow认为我的问题主要是代码,需要更多的细节。我以前遇到过这种恼人的限制。如果我能用几句话清楚地问我的问题,我应该可以。我会看看是否能找到指向该问题的链接,如果可以,我会在这里添加链接。)

这是我看到光标使用的地方

使用光标的优点是什么

唯一的优点是你必须编写更多的代码(如果他们为每行代码付费)

只需打开一个(虚拟)光标,获取行,检查范围,在需要时退出,然后为您关闭光标

do $$
declare
    rec record;
begin
    for rec in select i from generate_series(1, 3) i
    loop
        raise notice '%', rec.i;
    end loop;
end
$$;
使用光标的优点是什么

唯一的优点是你必须编写更多的代码(如果他们为每行代码付费)

只需打开一个(虚拟)光标,获取行,检查范围,在需要时退出,然后为您关闭光标

do $$
declare
    rec record;
begin
    for rec in select i from generate_series(1, 3) i
    loop
        raise notice '%', rec.i;
    end loop;
end
$$;

有几种方法:

  • 在PL/pgSQL中使用一个显式游标,循环遍历它并处理每个结果行

    例如:

    OPEN c FOR SELECT id FROM a WHERE ok;
    LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    FOR c IN SELECT id FROM a WHERE ok LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    UPDATE b SET a_ok = TRUE
    FROM a
    WHERE a.id = b.a_id AND a.ok;
    
  • 在选择中为r使用
    。。。PL/pgSQL中的循环
    。这实际上与1相同。语法更清晰

    例如:

    OPEN c FOR SELECT id FROM a WHERE ok;
    LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    FOR c IN SELECT id FROM a WHERE ok LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    UPDATE b SET a_ok = TRUE
    FROM a
    WHERE a.id = b.a_id AND a.ok;
    
  • 在不使用光标的情况下运行
    SELECT
    查询,并在客户端处理每个结果行,可能会对每个结果发出数据库查询

    示例(伪代码):

  • 使用
    连接

    例如:

    OPEN c FOR SELECT id FROM a WHERE ok;
    LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    FOR c IN SELECT id FROM a WHERE ok LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    UPDATE b SET a_ok = TRUE
    FROM a
    WHERE a.id = b.a_id AND a.ok;
    
  • 方法3。这是解决问题最糟糕的方法,因为它会导致大量客户机-服务器往返,并让数据库解析大量语句。 唉,SQL新手通常就是这样解决问题的。我称之为本地生成的嵌套循环联接。 最重要的是,客户端软件通常会将第一次查询的完整结果集snarf到内存中,这会导致另一个问题

    方法1。二,。是相等的,除了2。它更优雅。它保存了往返,并在后台使用准备好的语句,因此不必一直解析
    UPDATE
    。尽管如此,执行器必须运行很多次,而且众所周知PL/pgSQL并不是特别快。它也是一种自行开发的嵌套循环联接


    方法4是前进的方向。不仅所有内容都在一个查询中运行,而且如果更好的话,PostgreSQL还可以使用更有效的连接策略。

    有几种方法:

  • 在PL/pgSQL中使用一个显式游标,循环遍历它并处理每个结果行

    例如:

    OPEN c FOR SELECT id FROM a WHERE ok;
    LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    FOR c IN SELECT id FROM a WHERE ok LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    UPDATE b SET a_ok = TRUE
    FROM a
    WHERE a.id = b.a_id AND a.ok;
    
  • 在选择中为r使用
    。。。PL/pgSQL中的循环
    。这实际上与1相同。语法更清晰

    例如:

    OPEN c FOR SELECT id FROM a WHERE ok;
    LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    FOR c IN SELECT id FROM a WHERE ok LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    UPDATE b SET a_ok = TRUE
    FROM a
    WHERE a.id = b.a_id AND a.ok;
    
  • 在不使用光标的情况下运行
    SELECT
    查询,并在客户端处理每个结果行,可能会对每个结果发出数据库查询

    示例(伪代码):

  • 使用
    连接

    例如:

    OPEN c FOR SELECT id FROM a WHERE ok;
    LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    FOR c IN SELECT id FROM a WHERE ok LOOP
       UPDATE b SET a_ok = TRUE WHERE a_id = c.id;
    END LOOP;
    
    UPDATE b SET a_ok = TRUE
    FROM a
    WHERE a.id = b.a_id AND a.ok;
    
  • 方法3。这是解决问题最糟糕的方法,因为它会导致大量客户机-服务器往返,并让数据库解析大量语句。 唉,SQL新手通常就是这样解决问题的。我称之为本地生成的嵌套循环联接。 最重要的是,客户端软件通常会将第一次查询的完整结果集snarf到内存中,这会导致另一个问题

    方法1。二,。是相等的,除了2。它更优雅。它保存了往返,并在后台使用准备好的语句,因此不必一直解析
    UPDATE
    。尽管如此,执行器必须运行很多次,而且众所周知PL/pgSQL并不是特别快。它也是一种自行开发的嵌套循环联接

    方法4是前进的方向。不仅所有内容都在一个查询中运行,而且PostgreSQL还可以使用更有效的连接策略(如果这样更好的话)