Поддержка Oracle и MySQL: насколько похож их синтаксис SQL? - PullRequest
5 голосов
/ 14 ноября 2009

Мы используем Oracle в проекте и хотели бы также поддерживать MySQL. Насколько близки их диалекты SQL?

Возможно ли вообще использовать один и тот же источник SQL для обоих без чрезмерной гимнастики?

Детали:

  • Мы используем iBatis, менеджер персистентности, который аккуратно разделяет операторы SQL в файлы ресурсов. Но мы работаем на уровне SQL, который имеет свои преимущества (и недостатки).
  • Мы бы предпочли не переходить на объектно-реляционный картограф, такой как Hibernate, который полностью защитил бы нас от различий в диалектах.
  • Мы очень старались придерживаться общего подмножества Oracle SQL.
  • Там нет PL / SQL.
  • Мы не используем хранимые процедуры или триггеры (пока, во всяком случае).
  • Мы используем проверочные ограничения, ограничения уникальности и ограничения внешнего ключа.
  • Мы используем НА УДАЛЕННЫХ КАСКАДАХ.
  • Мы используем транзакции (выполняется на уровне API iBatis).
  • Мы вызываем несколько функций отметки времени Oracle в запросах.
  • Мы бы использовали механизм хранения InnoDB с MySQL (он поддерживает транзакции и ограничения).

Так что вы думаете? Нужно ли нам поддерживать два разных набора файлов ресурсов iBatis SQL, по одному для каждого диалекта, или можно иметь один набор SQL, поддерживающий как MySQL, так и Oracle?

Окончательное обновление: Спасибо за все ответы, и особенно за ссылки на страницу Троэльса Арвина о различиях. Очень жаль, что стандарт не более, ну, стандарт. Для нас проблемы оказываются автоинкрементом MySQL против последовательности Oracle, LIMIT MySQL против Rowumber () Oracle и, возможно, нечетной или двумя функциями. Большинство всего остального следует передать довольно легко, по модулю несколько правок, чтобы убедиться, что мы используем SQL-92, как указывает @mjv. Большая проблема в том, что некоторые запросы могут нуждаться в ручной оптимизации по-разному в каждой СУБД.

Ответы [ 5 ]

9 голосов
/ 14 ноября 2009

Ожидайте несколько незначительных неровностей на дороге, но в целом должно быть относительно легко.

Из списка функций, которые вы используете в настоящее время, должно быть только несколько синктических или семантических различий, которые, как правило, легко исправить или учесть. Тот факт, что вы не используете PL / SQL и / или хранимые процедуры, является плюсом. Хорошее правило - придерживаться SQL-92, который поддерживается большинством СУБД, в частности Oracle и MySQL. (Обратите внимание, что это не текущий стандарт SQL, который является SQL-2008).

Несколько различий:

  • "LIMIT" является известным: для ограничения количества строк, которые нужно извлечь в списке результатов, MySQL использует LIMIT n, в конце запроса Oracle использует RowNumber () в предложении WHERE (что является болью, для вас также нужно ссылаться на него в списке SELECT ...)
  • Некоторые типы данных отличаются. Я думаю, в основном BOOLEAN (но кто использует это ;-)) Также некоторые, я думаю, тонкие различия с типом / форматом DATETIME.
  • Некоторые имена функций различаются (SUBSTRING и SUBSTR и т. Д.)

Только что нашел, что кажется хорошим ресурсом о различиях между реализациями SQL .

Чтение ответов от других, да, DDL, может быть проблемой. Я не учел, что, вероятно, поскольку многим приложениям не требуется DDL, вам просто нужно сразу установить схему данных и т. Д., А затем просто использовать SQL для запросов, добавления или обновления данных.

7 голосов
/ 14 ноября 2009

Я считаю, что поддержка единого набора файлов ресурсов SQL с MySQL и Oracle имеет несколько недостатков, поскольку они оказываются между обратной совместимостью и решением конкретной проблемы. Лучше всего иметь 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)

Вы можете проверить это Сравнение различных реализаций SQL

4 голосов
/ 16 ноября 2009

В дополнение к тому, что упоминали другие, 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 голосов
/ 14 ноября 2009

Вы определенно не сможете сохранить свой DDL таким же. Что касается DML, есть много сходств (есть базовое подмножество стандарта ANSI SQL, поддерживаемое каждой базой данных), но есть и некоторые различия.

Для начала MySQL использует значения автоинкремента, а Oracle использует последовательности. Это можно обойти (последовательность + триггер на стороне Oracle для имитации автоинкремента), но она есть. Встроенные функции совершенно разные.

По сути, в зависимости от того, что именно вы намереваетесь использовать, может быть или не быть возможным сохранить один набор утверждений для обоих. Кстати, даже с диалектами Hibernate не всегда возможно иметь один и тот же набор запросов - HQL хорош, но не всегда достаточно.

2 голосов
/ 15 ноября 2009

Oracle рассматривает пустые строки как нули. MySQL обрабатывает пустые строки как пустые строки, а нулевые строки - как нулевые.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...