PostgreSQL使用函数实现merge功能http://www.bieryun.com/3263.html
实验环境
操作系统:windows 10 家庭中文版
数据库系统: PostgreSQL 9.6.2
说明
oracle数据库中有merge函数,可在插入数据前判断:如果指定列数据不存在,则正常插入数据;如果指定列数据存在,则将此条数据更新为插入的数据。
postgresql数据库中没有类似自带函数,只能自己实现此功能
实验
开启数据库:
psql (9.6.2)
postgres=# \l
数据库列表
名称 | 拥有者 | 字元编码 | 校对规则 | Ctype | 存取权限
-------------+----------+----------+--------------------------------+--------------------------------+-----------------------
ag01xinku | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 |
postgres | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 |
template0 | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 | =c/postgres +
| | | | | postgres=CTc/postgres
test | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 |
wcm20171005 | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 |
(6 行记录)
postgres=# \c test
创建测试表db,并插入测试数据:
test=# CREATE TABLE db (a INT PRIMARY KEY, b TEXT);
CREATE TABLE
test=# INSERT INTO db VALUES(1,'1');
INSERT 0 1
test=# INSERT INTO db VALUES(2,'2');
INSERT 0 1
test=# SELECT a,b FROM db;
a | b
---+---
1 | 1
2 | 2
(2 行记录)
针对这个表创建merge函数:
test=# CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS
test-# $$
test$# BEGIN
test$# LOOP
test$# UPDATE db SET b = data WHERE a = key;
test$# IF found THEN
test$# RETURN;
test$# END IF;
test$#
test$# BEGIN
test$# INSERT INTO db(a,b) VALUES (key, data);
test$# RETURN;
test$# EXCEPTION WHEN unique_violation THEN
test$# -- do nothing
test$# END;
test$# END LOOP;
test$# END;
test$# $$
test-# LANGUAGE plpgsql;
CREATE FUNCTION
测试
使用merge函数插入key列字段已经在表中存在的数据:
test=# SELECT merge_db(1, 'a');
merge_db
----------
(1 行记录)
检查可发现,key字段为1的数据被更新了
test=# SELECT a,b FROM db;
a | b
---+---
2 | 2
1 | a
(2 行记录)
再尝试使用merge函数插入key列字段已经在表中不存在的数据:
test=# SELECT merge_db(3, 'c');
merge_db
----------
(1 行记录)
检查可发现数据直接插入了表中
test=# SELECT a,b FROM db;
a | b
---+---
2 | 2
1 | a
3 | c
(3 行记录)
功能实现!
小结
此方法只实现了oracle中merge函数的部分功能,而最大的问题是必须针对每个表创建自己的merge函数,比较适合在进行数据库迁移的时候配合外部表和触发器使用,而在正常业务环境中使用机会不多。