可以批量对数组元素进行删除,原文链接
http://blog.163.com/digoal@126/blog/static/163877040201261273149437/,在这篇 blog 中
德哥新增了函数 multi_text_array_remove (i_src text[],i_remove text[]) 用来应对数组中
多个元素删除的情况:
例如
数组 ARRAY[1,2,3,4,5]
如果要去掉一个元素,可以用 array_remove 函数 ( 这个函数在9.3 版本中才会有 ),但这个函数
只能删除一个元素,如果要去除多个元素,则可调用函数 multi_text_array_remove
--multi_text_array_remove 函数演示@H_404_16@
postgres=# select multi_text_array_remove(ARRAY['abc','a','c','d'],ARRAY['a','d']); multi_text_array_remove ------------------------- {abc} (1 row) |
那么添加数组元素情况如何呢?在 Postgresql 中已经有函数 array_append 函数,但是这个函数
只能一次添加一个元素,如果想添加多个,需要多次调用。
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+--------------+------------------+----------------------+--------
pg_catalog | array_append | anyarray | anyarray,anyelement | normal
(1 row)
francs=> select array_append(array[1,3],4);
array_append
--------------
{1,4}
(1 row)
根据德哥的函数,依葫芦画瓢,这里写一个 int4[] 类型数组元素批量增加的函数
--1.1 创建 multi_array_append_int4 函数@H_404_16@
DECLARE
v_text int4;
v_result int4[];
BEGIN
v_result := i_src;
if i_append is null then
return v_result;
end if;
foreach v_text in ARRAY i_append loop
select array_append(v_result,v_text) into v_result;
end loop;
return v_result;
END;
$$ LANGUAGE 'plpgsql';
可参考本文末尾的附一。
--1.2 multi_array_append_int4 函数测试 1@H_404_16@
multi_array_append_int4
-------------------------
{1,4}
(1 row)
francs=> select multi_array_append_int4(array[1,array[4,5]);
multi_array_append_int4
-------------------------
{1,5}
(1 row)
francs=> select multi_array_append_int4(array[1,null);
multi_array_append_int4
-------------------------
{1,3}
(1 row)
--1.3 multi_array_append_int4 函数测试 2@H_404_16@
francs=> \set b 5
francs=> select multi_array_append_int4(array[1,array[:a,:b]);
@H_404_16@multi_array_append_int4
-------------------------
{1,5}
--2.1 创建 multi_array_append_text 函数
DECLARE
v_text text;
v_result text[];
BEGIN
v_result := i_src;
if i_append is null then
return v_result;
end if;
foreach v_text in ARRAY i_append loop
select array_append(v_result,230)"> --2.2 测试@H_404_16@
multi_array_append_text
-------------------------
{a,b,c}
(1 row)
francs=> select multi_array_append_text(array['a',array['d']);
multi_array_append_text
-------------------------
{a,c,d}
(1 row)
francs=> select multi_array_append_text(array['a',array['d','e']);
multi_array_append_text
-------------------------
{a,d,e}
(1 row)
--3 附一 : Looping Through Arrays
@H_404_16@ The FOREACH loop is much like a FOR loop,but instead of iterating through the rows returned by a
sql query,it iterates through the elements of an array value. (In general,FOREACH is meant for looping
through components of a composite-valued expression; variants for looping through composites besides arrays
may be added in future.) The FOREACH statement to loop over an array is:
[ <<label>> ]
FOREACH target [ SLICE number ] IN ARRAY expression LOOP
statements
END LOOP [ label ];
--4 参考
@H_404_16@http://blog.163.com/digoal@126/blog/static/163877040201261273149437/
http://www.postgresql.org/docs/9.1/static/plpgsql-control-structures.html
http://www.depesz.com/2012/07/12/waiting-for-9-3-add-array_remove-and-array_replace-functions/comment-page-1/#comment-35948
前段时间一位开发的同事问我,ARRAY类型有没有原子的替换和删除ARRAY元素的操作,用于好友列表(array类型)的更新,删除好友用得比较多。替换操作可能用得比较少。添加好友的话现在的Postgresql就已经支持原子操作了。
begin;select column_array from table where pk_id=?for update; --这一步是防止其他进程对这条记录进行读取和修改。(这也是用BEGINCOMMIT;的原因)update table set column_array=ARRAY[1,45] =?commit;
1.下载源码https:@H_890_404@//github.com/postgres/postgres/tarball/master@H_890_404@2. 编译安装@H_890_404@useradd pg@H_890_404@./configure --prefix=/home/pg/pgsql --with-pgport=5433 --with-perl --with-python --with-tcl --with-openssl --with-pam --without-ldap --with-libxml --with-libxslt --enable-thread-safety --enable-debug--with-wal-blocksize=16 && gmake world@H_890_404@sudo gmake install-world@H_890_404@initdb -A md5 -D $PGDATA -E UTF8 --locale=C -W -U postgres@H_890_404@略@H_890_404@pg_ctl start
postgres=@H_890_404@# select proname from pg_proc where proname ~ 'array' order by proname;@H_890_404@ proname@H_890_404@-----------------------@H_890_404@_pg_expandarray@H_890_404@anyarray_in@H_890_404@anyarray_out@H_890_404@anyarray_recv@H_890_404@anyarray_send@H_890_404@anynonarray_in@H_890_404@anynonarray_out@H_890_404@array_agg@H_890_404@array_agg_finalfn@H_890_404@array_agg_transfn@H_890_404@array_append@H_890_404@array_cat@H_890_404@array_dims@H_890_404@array_eq@H_890_404@array_fill@H_890_404@array_ge@H_890_404@array_gt@H_890_404@array_in@H_890_404@array_larger@H_890_404@array_le@H_890_404@array_length@H_890_404@array_lower@H_890_404@array_lt@H_890_404@array_ndims@H_890_404@array_ne@H_890_404@array_out@H_890_404@array_prepend@H_890_404@array_recv@H_890_404@array_send@H_890_404@array_smaller@H_890_404@array_to_string@H_890_404@array_upper@H_890_404@arraycontained@H_890_404@arraycontains@H_890_404@arrayoverlap@H_890_404@btarraycmp@H_890_404@ginarrayconsistent@H_890_404@ginarrayextract@H_890_404@ginqueryarrayextract@H_890_404@hash_array@H_890_404@regexp_split_to_array@H_890_404@string_to_array@H_890_404@(47 rows)
# create table pg91_array_funcs(proname text);
# select proname from pg_proc where proname ~ 'array' and proname not in (select trim(proname) from pg91_array_funcs);
# \df+ *.*array_replace*
# create table user_contact_info(id serial primary key,username text unique,phonenum text,contacts text[]);
# update user_contact_info set contacts = array_replace(contacts,'13988888888','123456') where username='digoal';
# update user_contact_info set contacts = array_remove(contacts,0)">id | username | phonenum | contacts
# select array[1,1,4],array_remove(array[1,1),array_remove(array_remove(array[1,2);
# create or replace function multi_text_array_remove(i_src text[],i_remove text[]) returns text[] as $$@H_890_404@declare@H_890_404@v_text text;@H_890_404@v_result text[];@H_890_404@begin@H_890_404@v_result := i_src;@H_890_404@foreach v_text in ARRAY i_remove@H_890_404@loop@H_890_404@ select array_remove(v_result,v_text) into v_result;@H_890_404@end loop;@H_890_404@return v_result;@H_890_404@end;@H_890_404@CREATE FUNCTION@H_890_404@postgres=# select multi_text_array_remove(ARRAY['abc','d']);@H_890_404@multi_text_array_remove@H_890_404@-------------------------@H_890_404@{abc}@H_890_404@(1 row)