MERGE INTO
功能描述
通过MERGE INTO语句,将目标表和源表中数据针对关联条件进行匹配,若关联条件匹配时对目标表进行UPDATE,无法匹配时对目标表执行INSERT。此语法可以很方便地用来合并执行UPDATE和INSERT,避免多次执行。
注意事项
- 进行MERGE INTO操作的用户需要同时拥有目标表的UPDATE和INSERT权限,以及源表的SELECT权限。
- 本章节只包含shark新增的语法,原openGauss的语法未做删除和修改。原openGauss的MERGE INTO语法请参考章节MERGE INTO。
- 新增支持table_hint子句。
语法格式
1. MERGE [/*+ plan_hint */] INTO table_name [ partition_clause ] [ [ AS ] alias ]
2. USING { { table_name | view_name } | subquery } [ [ AS ] alias ] [table_hint_clause]
3. ON ( condition )
4. [
5. WHEN MATCHED THEN
6. UPDATE SET { column_name = { expression | subquery | DEFAULT } |
7. ( column_name [, ...] ) = ( { expression | subquery | DEFAULT } [, ...] ) } [, ...]
8. [ WHERE condition ]
9. ]
10. [
11. WHEN NOT MATCHED THEN
12. INSERT { DEFAULT VALUES |
13. [ ( column_name [, ...] ) ] VALUES ( { expression | subquery | DEFAULT } [, ...] ) [, ...] [ WHERE condition ] }
14. ];
15. NOTICE: 'subquery' in the UPDATE and INSERT clauses are only avaliable in CENTRALIZED mode!
- 其中table_hint子句table_hint_clause为:
1. WITH ( <table_hint> [, ...] )
参数说明
-
WITH ( <table_hint> [, …] )
-
与SELECT子句相同,在未给出WITH时,table_hint仅支持给出一个hint,在给出WITH时,table_hint支持给出一个列表选项,列表通过逗号或者空格分隔,即(hint1)、WITH (hint1)、WITH (hint1, hint2, …)、WITH (hint1 hint2 …)均支持。
- 支持的hint包括NOLOCK、READUNCOMMITTED、UPDLOCK、REPEATABLEREAD、SERIALIZABLE、READCOMMITTED、TABLOCK、TABLOCKX、PAGLOCK、ROWLOCK、NOWAIT、READPAST、XLOCK、SNAPSHOT、NOEXPAND。
- 当上述hint需要当做标识符,用于列名、变量名等,需要设置d_format_behavior_compat_options = ‘enable_table_hint_identifier’,该变量默认值d_format_behavior_compat_options = ‘’。
- 所有的hint仅语法支持,无实际含义。
- 针对hint,会打印相关NOTICE信息。
示例
1. -- 创建目标表products和源表newproducts,并插入数据
2. openGauss=# CREATE TABLE products
3. (
4. product_id INTEGER,
5. product_name VARCHAR2(60),
6. category VARCHAR2(60)
7. );
9. openGauss=# INSERT INTO products VALUES (1501, 'vivitar 35mm', 'electrncs');
10. openGauss=# INSERT INTO products VALUES (1502, 'olympus is50', 'electrncs');
11. openGauss=# INSERT INTO products VALUES (1600, 'play gym', 'toys');
12. openGauss=# INSERT INTO products VALUES (1601, 'lamaze', 'toys');
13. openGauss=# INSERT INTO products VALUES (1666, 'harry potter', 'dvd');
15. openGauss=# CREATE TABLE newproducts
16. (
17. product_id INTEGER,
18. product_name VARCHAR2(60),
19. category VARCHAR2(60)
20. );
22. openGauss=# INSERT INTO newproducts VALUES (1502, 'olympus camera', 'electrncs');
23. openGauss=# INSERT INTO newproducts VALUES (1601, 'lamaze', 'toys');
24. openGauss=# INSERT INTO newproducts VALUES (1666, 'harry potter', 'toys');
25. openGauss=# INSERT INTO newproducts VALUES (1700, 'wait interface', 'books');
27. -- 进行MERGE INTO操作
28. openGauss=# MERGE INTO products p
29. USING newproducts np
30. ON (p.product_id = np.product_id)
31. WHEN MATCHED THEN
32. UPDATE SET p.product_name = np.product_name, p.category = np.category WHERE p.product_name != 'play gym'
33. WHEN NOT MATCHED THEN
34. INSERT VALUES (np.product_id, np.product_name, np.category) WHERE np.category = 'books';
35. MERGE 4
37. -- 查询更新后的结果
38. openGauss=# SELECT * FROM products ORDER BY product_id;
39. product_id | product_name | category
40. ------------+----------------+-----------
41. 1501 | vivitar 35mm | electrncs
42. 1502 | olympus camera | electrncs
43. 1600 | play gym | toys
44. 1601 | lamaze | toys
45. 1666 | harry potter | toys
46. 1700 | wait interface | books
47. (6 rows)
49. -- 进行MERGE INTO操作
50. MERGE INTO products p
51. USING newproducts np with (nowait)
52. ON (p.product_id = np.product_id)
53. WHEN MATCHED THEN
54. UPDATE SET p.product_name = np.product_name, p.category = np.category WHERE p.product_name != 'play gym'
55. WHEN NOT MATCHED THEN
56. INSERT VALUES (np.product_id, np.product_name, np.category) WHERE np.category = 'books';
57. NOTICE: The nowait option is currently ignored
58. MERGE 4
60. -- 查询更新后的结果
61. openGauss=# SELECT * FROM products with (nowait) ORDER BY product_id;
62. NOTICE: The nowait option is currently ignored
63. product_id | product_name | category
64. ------------+----------------+-----------
65. 1501 | vivitar 35mm | electrncs
66. 1502 | olympus camera | electrncs
67. 1600 | play gym | toys
68. 1601 | lamaze | toys
69. 1666 | harry potter | toys
70. 1700 | wait interface | books
71. (6 rows)
73. -- 进行MERGE INTO操作
74. MERGE INTO products p
75. USING newproducts np (nowait)
76. ON (p.product_id = np.product_id)
77. WHEN MATCHED THEN
78. UPDATE SET p.product_name = np.product_name, p.category = np.category WHERE p.product_name != 'play gym'
79. WHEN NOT MATCHED THEN
80. INSERT VALUES (np.product_id, np.product_name, np.category) WHERE np.category = 'books';
81. NOTICE: The nowait option is currently ignored
82. MERGE 4
84. -- 查询更新后的结果
85. openGauss=# SELECT * FROM products with (nowait) ORDER BY product_id;
86. NOTICE: The nowait option is currently ignored
87. product_id | product_name | category
88. ------------+----------------+-----------
89. 1501 | vivitar 35mm | electrncs
90. 1502 | olympus camera | electrncs
91. 1600 | play gym | toys
92. 1601 | lamaze | toys
93. 1666 | harry potter | toys
94. 1700 | wait interface | books
95. (6 rows)
97. -- 删除表
98. openGauss=# DROP TABLE products;
99. openGauss=# DROP TABLE newproducts;
