创建plpgsql函数,为数组中的每个项插入一行到表中

时间:2013-07-29 07:04:16

标签: postgresql plpgsql postgresql-9.2

我需要创建一个plpgsql函数,将数组中每个项目的一行插入表格。

例如: the_array = [1,2,3]

the_array插入temp_table后的结果:

col
----
1
2
3

我在此链接中找到以下代码: http://postgresql.1045698.n5.nabble.com/insert-into-table-from-list-or-array-td3217891.html

INSERT INTO tmptab 
   SELECT v 
     FROM unnest(string_to_array('1,2,4,2,1',',')) g(v) 

它就像一个魅力,但我不明白这段代码是如何工作的。 有人可以帮我解释一下吗?

2 个答案:

答案 0 :(得分:1)

函数string_to_array('1,2,4,2,1', ',')从字符串创建一个数组,因此您可以使用ARRAY[1,2,4,2,1]代替。

函数unnest(array)将数组扩展为一组行。所以你有一组五行,每行都有整数。

需要最后一部分g(v),因为您需要命名行集及其列。

因此整个unnest(string_to_array('1,2,4,2,1',','))返回一组行,每行包含一列。它已映射到g(v),因此您可以使用v作为值。

如果你有一个像create table g(v integer);这样的表并在那里插入值为1,2,4,2,1的行,那么你将获得相同的结果:

INSERT INTO tmptab 
   SELECT v 
     FROM g; 

答案 1 :(得分:1)

PostgreSQL支持Set Returning Function(第二个名称是表格函数)。此类中的函数返回表而不是标量值。有很多用例 - 一个用例是一个“不需要”的函数

CREATE OR REPLACE FUNCTION simple_srf(int)
RETURNS SETOF int AS $$
BEGIN
  FOR i IN 1..$1
  LOOP
    RETURN NEXT i; -- push value to result
  END LOOP;
  RETURN; -- finish execution
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;

postgres=# SELECT * FROM simple_srf(3);
 simple_srf 
------------
          1
          2
          3
(3 rows)

函数“string_to_array”使用separator to array解析字符串。

postgres=# select string_to_array('aaa*bbb*ccc','*');
 string_to_array 
-----------------
 {aaa,bbb,ccc}
(1 row)

Unnest是一个简单的函数,它将数组转换为表格。 plpgsql中此函数的源代码可以是:

-- use PostgreSQL 8.4 syntax for simplicity
CREATE OR REPLACE FUNCTION unnest(anyarray)
RETURNS SETOF anyelement AS $$
BEGIN
  FOR i IN array_lower($1,1) .. array_upper($1,1)
  LOOP
    RETURN NEXT $1[i];
  END LOOP;
  RETURN;
END;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;

“Unnest”是一个多态集返回函数。 PostgreSQL支持更多内置srf(表格)函数 - 例如generic_series或generate_subscripts

“不需要”功能的较早实现是:

CREATE OR REPLACE FUNCTION unnest(anyarray)
RETURNS anyelement AS $$
SELECT $1[i] FROM generate_series(array_lower($1,1),array_upper($1,1)) g(i)
$$ LANGUAGE sql;

-- or with generate_subscripts
CREATE OR REPLACE FUNCTION unnest(anyarray)
RETURNS anyelement AS $$
/*
 * g is a table alias
 * i is a column alias
 */
SELECT $1[i] FROM generate_subscripts($1,1) g(i)
$$ LANGUAGE sql;