如何选择多个值到数组中并循环?(postgres 9.3)

Ale*_*ans 3 postgresql aggregate array

为了便于论证,我有一个简单的表格。我有一个选择 ids 并循环它们的函数,称为loop_test. 我可以选择一个 id 数组并循环它们,从而导致我在事务中进行更改。

CREATE OR REPLACE FUNCTION loop_test() RETURNS void AS $$
DECLARE
        _ids_array INTEGER[];
        _id INTEGER;
BEGIN
        SELECT ARRAY(SELECT id FROM loop_test) INTO _ids_array; 
        FOREACH _id IN ARRAY _ids_array
        LOOP
                UPDATE loop_test SET looped = TRUE WHERE id = _id;
        END LOOP;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

桌子:

db=# \d loop_test;
      Table "public.loop_test"
    Column     |  Type   | Modifiers 
---------------+---------+-----------
 id            | integer | 
 other_id      | integer | 
 id_copy       | integer | 
 other_id_copy | integer | 
 looped        | boolean | 

db=# select * from loop_test;
 id | other_id | id_copy | other_id_copy | looped 
----+----------+---------+---------------+--------
  1 |       10 |         |               | 
  6 |       15 |         |               | 
  2 |       11 |         |               | 
  7 |       16 |         |               | 
  3 |       12 |         |               | 
  4 |       13 |         |               | 
  5 |       14 |         |               | 
(7 rows)
Run Code Online (Sandbox Code Playgroud)

当我打电话时select loop_test(),我得到以下结果:

db=# select * from loop_test;
 id | other_id | id_copy | other_id_copy | looped 
----+----------+---------+---------------+--------
  1 |       10 |         |               | t
  6 |       15 |         |               | t
  2 |       11 |         |               | t
  7 |       16 |         |               | t
  3 |       12 |         |               | t
  4 |       13 |         |               | t
  5 |       14 |         |               | t
(7 rows)
Run Code Online (Sandbox Code Playgroud)

但是,我想创建一个函数来将id和 都选择other_id到数组中。有人告诉我使用类似的东西agg_array,但我不完全理解它是如何工作的。

我在想象类似下面的东西?

CREATE OR REPLACE FUNCTION agg_loop_test() RETURNS void AS $$
DECLARE
        _ids_array INTEGER[][];
        _id INTEGER;
BEGIN
        SELECT AGG_ARRAY(SELECT id, other_id FROM loop_test) INTO _ids_array;
        FOREACH _id IN ARRAY _ids_array
        LOOP
                UPDATE loop_test SET id_copy = _id[0], other_id_copy = _id[1] WHERE id = _id[0];
        END LOOP;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 9

更好的方法是:更新即可。不需要循环。

UPDATE loop_test
SET    id_copy = id
     , other_id_copy = other_id;
WHERE  id IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)

WHERE仅当条件可以为 null 并且您想要与您所拥有的条件完美等效时,该条件才有用id

环形

如果您只是探索循环 - 您可以分配多个变量。看:

CREATE OR REPLACE FUNCTION better_loop_test()
  RETURNS void
  LANGUAGE plpgsql AS
$func$
DECLARE
   _id int;
   _other_id int;
BEGIN
   -- example makes no sense, just a loop demo
   FOR _id, _other_id IN
      SELECT id, other_id FROM loop_test
   LOOP
      UPDATE loop_test
      SET    id_copy = _id
           , other_id_copy = _other_id
      WHERE id = _id;
   END LOOP;
END
$func$;
Run Code Online (Sandbox Code Playgroud)

虽然您只需要已知类型的两列,但这可能比获取整个(可能很大)行便宜一些。