支持Oracle和MySQL:它们的SQL语法有多相似?

时间:2009-11-14 04:29:32

标签: java sql mysql oracle ibatis

我们在项目中使用Oracle,并且也想支持MySQL。他们的SQL方言有多接近?

在没有太多体操的情况下,甚至可能为两者使用相同的SQL源吗?

详细说明:

  • 我们正在使用iBatis,一个将SQL语句干净地隔离到资源文件中的持久性管理器。但我们在SQL级别工作,这有其优点(和缺点)。
  • 我们不想转移到像Hibernate这样的对象关系映射器,它可以完全保护我们免受方言差异的影响。
  • 我们努力保持Oracle SQL的通用子集。
  • 没有PL / SQL。
  • 我们不使用存储过程或触发器(无论如何)。
  • 我们使用检查约束,唯一约束和外键约束。
  • 我们使用ON DELETE CASCADE。
  • 我们使用交易(在iBatis API级别完成)。
  • 我们在查询中调用了几个Oracle时间戳函数。
  • 我们会将InnoDB存储引擎与MySQL一起使用(它支持事务和约束)。

那你有什么想法?我们是否需要维护两组不同的iBatis SQL资源文件,每个方言一个,或者是否可以使用一组SQL支持MySQL和Oracle?

最终更新:感谢所有答案,尤其是指向Troels Arvin关于差异的页面的指示。令人遗憾的是,标准并不是更好,标准。对我们来说,问题结果是MySQL自动增量与Oracle序列,MySQL LIMIT与Oracle Rowumber(),也许是奇数函数或两个。大多数其他一切都应该很容易转移,模拟一些编辑,以确保我们使用SQL-92作为@mjv指出。更大的问题是某些查询可能需要在每个DBMS中进行不同的手动优化。

5 个答案:

答案 0 :(得分:9)

预计道路上会有一些轻微的颠簸,但总的来说应该相对容易。

从您当前使用的功能列表中,应该只有一些同义词或语义上的差异,通常很容易修复或解释。您不使用PL / SQL和/或存储过程这一事实是一个优点。一个好的经验法则是尝试坚持大多数DBMS支持的SQL-92,特别是Oracle和MySQL。 (注意,这不是当前SQL标准,即SQL-2008)。

一些差异:

  • “LIMIT”是一个着名的:要限制在结果列表中检索的行数,MySQL使用LIMIT n,在查询结束时,Oracle在WHERE子句中使用RowNumber()(这很痛苦,因为你还需要在SELECT列表中引用它...)
  • 有些数据类型不同。我认为主要是BOOLEAN(但是谁使用了这个;-))还有一些我认为与DATETIME类型/格式有细微差别。
  • 某些功能名称不同(SUBSTRING与SUBSTR等......)

刚刚找到了似乎是good resource about differences between SQL implementations的内容。

阅读其他人的回复,是的,DDL,可能是一个问题。我打了折扣,可能是因为许多应用程序不需要DDL,您只需要立即设置数据模式等,然后只使用SQL查询,添加或更新数据。

答案 1 :(得分:7)

我认为使用MySQL和Oracle维护一组SQL资源文件,在向后兼容性和解决特定问题之间存在一些缺点。最好为每个SQL引擎都有一个sql,从而最大化每个SQL引擎的功能。

小册子中看起来完全相同的功能可能会以非常不同的方式实施。

参见这些例子

限制结果集

<强> MYSQL

SELECT columns
FROM tablename
ORDER BY key ASC
LIMIT n

<强> ORACLE

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,
    columns
  FROM tablename
)
WHERE rownumber <= n

限制 - 带偏移量

<强> MYSQL

SELECT columns
FROM tablename
ORDER BY key ASC
LIMIT n OFFSET skip

<强> ORACLE

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY key ASC) AS rn,
    columns
  FROM tablename
)
WHERE rn > skip AND rn <= (n+skip)

您可以查看Comparison of different SQL implementations

答案 2 :(得分:4)

除了其他人提到的东西之外,oracle和mysql处理外连接的方式完全不同。实际上,Oracle提供了mySql无法处理的语法,但Oracle将处理标准语法。

仅限Oracle:

SELECT a.foo, b.bar
  FROM a, b
 WHERE a.foo = b.foo(+)

mySql和Oracle:

SELECT a.foo, b.bar
     FROM a 
LEFT JOIN b 
       ON (a.foo=b.foo)

所以你可能需要转换一些外连接。

答案 3 :(得分:3)

你肯定无法保持你的DDL一样。就DML而言,有许多相似之处(每个数据库都支持ANSI SQL标准的核心子集),但也存在一些差异。

首先,MySQL使用自动增量值,Oracle使用序列。可以解决这个问题(Oracle端的序列+触发器来模拟自动增量),但它就在那里。内置功能完全不同。

基本上,根据您打算使用的具体内容,可能会也可能无法为两者保留一组语句。顺便说一下,即使使用Hibernate方言,并不总是可以使用相同的查询集--HQL很棒,但并不总是足够。

答案 4 :(得分:2)

Oracle将空字符串视为空值。 MySQL将空字符串视为空字符串,将空字符串视为空字符串。