【问题标题】:Oracle MERGE statement in H2 databaseH2数据库中的Oracle MERGE语句
【发布时间】:2012-11-22 20:35:43
【问题描述】:

我们开始使用内存数据库中的 H2 进行自动化测试。我们将 Oracle 用于我们的生产和开发环境。所以我们的想法是复制 H2 测试数据库中的表结构,就像它在我们的 Oracle 开发数据库中一样。

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

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

要与 H2 兼容的 Oracle SQL 示例,

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

(T1 & T2 是表的别名)

【问题讨论】:

  • 您的项目选择了一种不同风格的数据库,一种具有不同 SQL 语法的数据库,用于自动化测试?福特。如果您必须重写您的应用程序以运行您的自动化测试,那么您的测试证明了什么?
  • 我们选择H2,因为它可以运行非常快的内存数据库。
  • 是的,但是如果它无法运行您在开发和生产中使用的 SQL 语法,那么无论测试运行多快都无关紧要。
  • 我看不出为什么这个问题被否决了 - 模拟 Oracle 语句语法 ('MODE=Oracle') 是 H2 的特性,并且在行业中运行快速集成是一种常见且良好的做法对内存数据库进行测试。

标签: sql h2 sql-merge


【解决方案1】:

MERGE statement in H2 的语法稍有不同:

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

我猜您必须编写两条语句,一条用于 H2,一条用于 Oracle。但是,SELECT 部分将是相同的。 The Oracle MERGE statement 会更长,我相信会是:

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 中为查询使用别名?
  • 是的,但这不是别名。语句的整个语法不同。
【解决方案2】:

标准 SQL 合并语法支持目前在 H2 的 the roadmap 上。

但是,在某些简单的情况下,您可以使用 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。

【讨论】:

    【解决方案3】:

    我是 2019 年的。H2 支持标准的“MERGE INTO ... USING ... WHEN ...”。 Documentation

    【讨论】:

      猜你喜欢
      • 2017-01-18
      • 2017-05-23
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 2013-12-13
      • 1970-01-01
      • 2013-07-16
      • 2013-06-11
      相关资源
      最近更新 更多