huacuilaifa 2019-12-23
多表关联查询的时候会用到临时表插入数据,然后再用select查行查询,在往临时表里插入数据的时候,我们经常会用到判断如果临时表里有了这部分数据我们就要更新数据,如果临时表里没有这部分数据我们就要插入,这个时候可以怎么去实现呢?
下面介绍Oracle的merge into和pg数据库自定义函数实现方式。
1、语法
merge语法是根据源表对目标表进行匹配查询,匹配成功时更新,不成功时插入。
MERGE INTO [target-table] A USING [source-table sql] B ON([conditional expression] and [...]...)WHEN MATCHED THEN[UPDATE sql]WHEN NOT MATCHED THEN[INSERT sql]
2、实验
1)环境准备
--建表create table t1(id number,name VARCHAR(16),sale number,Operatime date);create table t2(id number,name VARCHAR(16),sale number);-- 插入数据INSERT into t1 values(1,'xiaohong',1000,sysdate);INSERT into t1 values(2,'xiaoming',500,sysdate);INSERT into t2 values(1,'xiaohong',300);INSERT into t2 values(2,'xiaoming',400);INSERT into t2 values(3,'xiaoxiao',900);commit;
2)Oracle merge into实现
merge into t1 using t2 on (t1.id=t2.id) WHEN MATCHED THENupdate set t1.sale=t2.saleWHEN NOT MATCHED THENinsert values(t2.id,t2.name,t2.sale,sysdate);
oracle数据库中有merge函数,可在插入数据前判断:如果指定列数据不存在,则正常插入数据;如果指定列数据存在,则将此条数据更新为插入的数据。 postgresql数据库中没有类似自带函数,只能自己实现此功能
以下方法只实现了oracle中merge函数的部分功能,而最大的问题是必须针对每个表创建自己的merge函数,比较适合在进行数据库迁移的时候配合外部表和触发器使用。
1、环境准备
--建表create table t1(id int PRIMARY KEY,name varchar(16),sale int,operatime timestamp with time zone);-- 插入数据INSERT into t1 values(1,'xiaohong',1000,now());INSERT into t1 values(2,'xiaoming',500,now());commit;
2、pg自定义函数实现
该函数基于表级别。
CREATE FUNCTION merge_db(id_new INT,name_new varchar(10),sale_new int) RETURNS VOID AS$$BEGINLOOP UPDATE t1 SET sale = sale_new WHERE id = id_new and name = name_new; IF found THEN RETURN; END IF;BEGIN INSERT INTO t1 VALUES (id_new,name_new,sale_new,now()); RETURN;EXCEPTION WHEN unique_violation THEN-- do nothingEND;END LOOP;END;$$LANGUAGE plpgsql;
3、实现
使用merge函数插入key列字段已经在表中存在的数据
select merge_db(1,'xiaohong',400);select merge_db(2,'xiaoming',300);select merge_db(3,'xiaoxiao',700);select * from t1;
觉得有用的朋友多帮忙转发哦!后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下~