【问题标题】:oracle grammar to h2 grammar (+) join tableoracle 语法到 h2 语法 (+) 连接表
【发布时间】:2015-12-31 04:06:24
【问题描述】:

我作为 Oracle 有以下查询

   SELECT DISTINCT count(pa.payment_id)   FROM
    location c,    inventory e,
    inventory_stock es,    payment_client ep,
    payment pa,    currency cur,
    location s,    exchange_country exc,
    exchange_rate sso,
    exchange_hike so,
    exchange_margin sov  WHERE
    cur.outState = 'N' AND
    c.location_id = e.location_id AND
    e.inventory_id = ep.inventory_id AND
    e.inventory_stock_id = es.inventory_stock_id AND
    ep.client_id = pa.end_client AND
    pa.cur_id = cur.cur_id AND
    cur.location_id = s.location_id AND
    c.client_id  is not null  AND
    cur.cur_id = exc.cur_id(+) AND
    exc.exchange_id = sso.exchange_id(+) AND
    sso.account_id = so.account_id(+) AND
    so.option_name(+)  = 'PREMIUM' AND
    exc.exchange_id = sov.exchange_id(+) AND
    sov.name(+)  = 'VALUE';

现在我正在使用 H2 数据库,我得到的语法错误来自 so.option_name(+)sov.name(+); 我知道 (+) 是 oracle 的右连接和左连接方式,但有没有可能的方法将其转换为h2 那么错误和语法是等价的吗?

【问题讨论】:

标签: database oracle join h2


【解决方案1】:

是时候继续前进了。 Oracle 不再推荐使用 Oracle 的旧外连接语法。 From the docs:

Oracle 建议您使用 FROM 子句 OUTER JOIN 语法而不是 Oracle 连接运算符。使用 Oracle 连接运算符 (+) 的外连接查询受以下规则和限制的约束,这些规则和限制不适用于 FROM 子句 OUTER JOIN 语法 [...]

如果您将 (+) 的用法替换为 outer join,那么您的查询不仅可以在 Oracle 和 H2 上运行,而且对于您的整个应用程序来说也是一个重要的进步。

SELECT DISTINCT count(pa.payment_id) 
FROM location c
JOIN inventory e ON c.location_id = e.location_id
JOIN payment_client ep ON e.inventory_id = ep.inventory_id
JOIN inventory_stock es ON e.inventory_stock_id = es.inventory_stock_id
JOIN payment pa ON ep.client_id = pa.end_client
JOIN currency cur ON pa.cur_id = cur.cur_id
JOIN location s ON cur.location_id = s.location_id
LEFT JOIN exchange_country exc ON cur.cur_id = exc.cur_id
LEFT JOIN exchange_rate sso ON exc.exchange_id = sso.exchange_id
LEFT JOIN exchange_hike so 
  ON sso.account_id = so.account_id
  AND so.option_name = 'PREMIUM'
LEFT JOIN exchange_margin sov 
  ON exc.exchange_id = sov.exchange_id
  AND sov.name = 'VALUE'
WHERE c.client_id IS NOT NULL
AND cur.outState = 'N'

(+) 转换为LEFT JOIN 时的重要性在于,您要密切注意哪些谓词必须进入ON 子句,以及哪些谓词可以在WHERE 子句中使用。特别是,以下两个谓词必须放在相关的左连接表的ON 子句中:

  • so.option_name(+) = 'PREMIUM'
  • sov.name(+) = 'VALUE'

第三方工具

你可以使用jOOQ的在线SQL translator在语法之间进行翻译,或者直接使用jOOQ到translate from table lists with Oracle joins to ansi joins

免责声明:我为 jOOQ 背后的公司工作

【讨论】:

  • This github issue 建议 H2 不支持完全外连接,因此“您的查询 [将在 Oracle 和 H2 上都有效]”这句话让我感到困惑
  • @Felk:我的回答不使用完全外连接,(+) 语法也不支持它......那么,你到底有什么困惑? :)
  • 是的,对不起。我没有注意到“外连接”隐含的意思是左外连接
  • @Felk:哦,我明白你的意思了。事实上,从技术上讲,Oracle 的文档并不完全准确。
猜你喜欢
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 2019-11-18
  • 1970-01-01
  • 2014-08-05
  • 2011-05-10
  • 1970-01-01
相关资源
最近更新 更多