H2数据库中的Oracle MERGE语句

16

我们开始使用H2内存数据库进行自动化测试。我们在生产和开发环境中使用Oracle数据库。因此,想法是在H2测试数据库中复制与Oracle开发数据库相同的表结构。

Oracle SQL语句包括MERGE语句,并在查询中使用表别名和USING。

如何动态修改此查询以与H2兼容,而不改变开发环境中现有的查询?

以下是需要与H2兼容的Oracle SQL示例:

MERGE INTO TABLE T1
USING ( SELECT ....
        ...........
        FROM DUAL) T2

(T1 和 T2 是该表的别名)


你的项目选择了一种不同的数据库类型,其SQL语法也不同,用于自动化测试?这可真是个棘手的问题。如果你必须重写你的应用程序,以便你的自动化测试运行,那么你的测试证明了什么呢? - APC
5
我们选择H2是因为它可以运行内存数据库,速度非常快。 - user1877775
是的,但如果它无法在开发和生产中运行您使用的SQL语法,则测试运行得有多快都没有意义,它们是无关紧要的。 - APC
7
我不明白为什么这个问题被投了反对票——在H2中模拟Oracle语句语法('MODE=Oracle')是其功能之一,在内存数据库上运行快速集成测试是业界常见且良好的做法。我认为这个问题有意义。 - Boris Treukhov
3个回答

12

H2中的MERGE语句具有稍微不同、更简单的语法:

MERGE INTO TEST(ID, NAME) KEY(ID)
SELECT 1, 'Hello' FROM DUAL

我猜你需要编写两个语句,一个针对H2,一个针对Oracle。然而,SELECT 部分是相同的。 Oracle MERGE 语句可能会更长,我认为它应该是这样的:
MERGE INTO TEST T
USING (SELECT 1 ID, 'Hello' NAME FROM DUAL) D
ON (T.ID = D.ID)
WHEN MATCHED THEN 
UPDATE SET T.NAME = D.NAME
WHEN NOT MATCHED THEN 
INSERT (B.ID, B.NAME) VALUES (D.ID, D.NAME);

感谢您的快速回复。那么,根据上面的语法,这是否意味着我不能在H2中使用查询的别名? - user1877775
是的,但它不是别名。整个语句的语法是不同的。 - Thomas Mueller

9
我来自2019年。H2支持标准的“MERGE INTO...USING...WHEN...”语法。文档

7

标准SQL合并语法支持目前在H2的路线图上。

然而,在一些简单情况下,您可以使用INSERT ... SELECT + WHERE NOT EXISTS,例如仅在记录不存在时插入。

INSERT INTO T1(K1, V2, V3) 
SELECT 1, 2, 3 FROM DUAL
  WHERE NOT EXISTS (SELECT 1 FROM T1 WHERE
K1 = 1 AND V2 = 2 AND V3 = 3);

这个构造在Oracle和H2中都可以工作(至少在MODE=Oracle模式下),所以您不必为测试和生产准备单独的SQL插入语句。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接