ITPub博客

首页 > 数据库 > 数据库开发技术 > 飘香新特性之Merge语法增强

飘香新特性之Merge语法增强

原创 数据库开发技术 作者:象楚之行 时间:2024-05-17 07:30:00 0 删除 编辑

即将发布的PG 17针对MERGE关键字有如下几点新特性:

Allow partitions to be merged using ALTER TABLE ... MERGE PARTITIONS (Dmitry Koval) 


Allow MERGE to modify updatable views (Dean Rasheed) 


Add WHEN NOT MATCHED BY SOURCE to MERGE (Dean Rasheed) 


Allow MERGE to use the RETURNING clause (Dean Rasheed)

https://www.postgresql.org/docs/devel/release-17.html

MERGE PARTITIONS的用法前几天写过文章:分区表的两大刚需|拆分分区 |合并分区

后面几点主要与Merge Into语法有关,而不是分区表的Merge。‍‍‍‍‍‍‍

PG 15引入的Merge语法参考如下

[ WITH with_query [, ...] ]
MERGE INTO target_table_name [ [ AS ] target_alias ]
USING data_source ON join_condition
when_clause [...]

PG 17对Merge Into语法增加了Returning子句

[ WITH with_query [, ...] ]
MERGE INTO target_table_name [ [ AS ] target_alias ]
USING data_source ON join_condition

when_clause [...][ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

本文将主要针对Merge语句增加的Returning子句进行测试。

参考六种常见的组合模式,在17里测试Merge语句与Returning子句

1.目标表匹配则执行update,不匹配则执行insert‍‍‍‍‍

用b_merge来更新a_merge中的数据:

merge into a_merge a

using (select b.aid,b.name,b.year from b_merge b) c on (a.id=c.aid)

when matched then

update set year=c.year

when not matched then

insert values(c.aid,c.name,c.year)

returning * ;

aid |   name   | year | id |   name   | year

-----+----------+------+----+----------+------

2 | zhangbin |   30 |  2 | zhangbin |   30

3 | fuguo    |      |  3 | fuguo    |

4 | yihe     |   33 |  4 | yihe     |   33

(3 rows)

MERGE 3

2.目标表匹配仅执行update‍‍

用b_merge来更新a_merge,但仅有update部分,没有insert部分。

merge into a_merge a

using (select b.aid,b.name,b.year from b_merge b) c on (a.id=c.aid)

when matched then

update set year=c.year

returning * ;

aid |   name   | year | id |   name   | year

-----+----------+------+----+----------+------

1 | liuwei   |   80 |  1 | liuwei   |   80

2 | zhangbin |   30 |  2 | zhangbin |   30

3 | fuguo    |      |  3 | fuguo    |

4 | yihe     |   33 |  4 | yihe     |   33

(4 rows)

MERGE 4

3.目标表不匹配仅执行insert

用b_merge来更新a_merge中的数据,此时只有insert,没有写update:

merge into a_merge a

using (select b.aid,b.name,b.year from b_merge b) c on (a.id=c.aid)

when not matched then

insert values(c.aid,c.name,c.year)

returning * ;

aid |   name   | year | id |   name   | year

-----+----------+------+----+----------+------

5 | tiantian |   23 |  5 | tiantian |   23

(1 row)

MERGE 1

4.二次匹配

在on中进行join匹配之后,还可以在后面的when子句中对on筛选出来的记录再做一次条件判断,控制哪些要更新,哪些要插入,哪些要删除。

用b_merge去更新a_merge,分别在insert和update后添加条件限制,控制数据的更新和插入:

merge into a_merge a

using (select b.aid,b.name,b.year,b.city from b_merge b) c on (a.id=c.aid)

when matched and c.city != '江西' then

update set name=c.name

when not matched and c.city = '江西' then

insert values(c.aid,c.name,c.year)

returning * ;

aid |   name   | year |  city  | id |   name   | year

-----+----------+------+--------+----+----------+------

2 | zhangbin |   70 | 吉林   |  2 | zhangbin |   30

3 | fuguo    |      | 山东   |  3 | fuguo    |

4 | yihe++   |   33 | 黑龙江 |  4 | yihe++   |   33

5 | tiantian |   23 | 河南   |  5 | tiantian |   23

6 | ningqin  |   23 | 江西   |  6 | ningqin  |   23

(5 rows)

MERGE 5

5.无条件insert

无条件全插入,on条件设置为永假,用b_merge来更新c_merge:

merge into c_merge c

using (select b.aid,b.name,b.city from b_merge b) b on (1=0)

when not matched then

insert values(b.aid,b.name,b.city)

returning * ;

aid |   name   |  city  | id |   name   |  city

-----+----------+--------+----+----------+--------

3 | fuguo    | 山东   |  3 | fuguo    | 山东

5 | tiantian | 河南   |  5 | tiantian | 河南

2 | zhangbin | 吉林   |  2 | zhangbin | 吉林

4 | yihe++   | 黑龙江 |  4 | yihe++   | 黑龙江

1 | liuwei++ | 江西   |  1 | liuwei++ | 江西

6 | ningqin  | 江西   |  6 | ningqin  | 江西

7 | bing     | 四川   |  7 | bing     | 四川

(7 rows)

MERGE 7

6.匹配则delete‍‍

when匹配子句里除了update,也可以执行delete子句。

用b_merge来匹配删除a_merge,删除时可进行二次匹配删除。

merge into a_merge a

using (select b.aid,b.name,b.year,b.city from b_merge b) c on (a.id=c.aid)

when matched and c.city = '江西' then

delete

returning * ;

aid |   name   | year | city | id |  name   | year

-----+----------+------+------+----+---------+------

1 | liuwei++ |   80 | 江西 |  1 | liuwei  |   80

6 | ningqin  |   23 | 江西 |  6 | ningqin |   23

(2 rows)

MERGE 2

只有符合关联条件且满足条件的数据才会被删除。

上面6个用例测试使用Returning子句可以返回insert插入的行或update修改的行或delete删除的行,但却看不出具体的DML操作类型。‍‍‍‍‍‍‍‍‍‍‍

使用merge_action()函数重测最后一个用例:

merge into a_merge a

using (select b.aid,b.name,b.year,b.city from b_merge b) c on (a.id=c.aid)

when matched and c.city = '江西' then

delete

returning a.*, merge_action() ;

id |  name   | year | merge_action

----+---------+------+--------------

1 | liuwei  |   80 | DELETE

6 | ningqin |   23 | DELETE

(2 rows)

MERGE 2

非常棒的功能!

原文作者:象楚之行;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2018-06-12

  • 博文量
    102
  • 访问量
    50370