Есть ли такая вещь, как переносимый SQL? - PullRequest
12 голосов
/ 13 апреля 2011

По моему опыту, даже несмотря на наличие стандарта SQL, довольно сложно написать SQL, который работает без изменений на большом количестве СУБД.

Таким образом, я хотел бы знать, существует ли подмножество SQL (включая DDL, схемы и т. Д.), Которое, как известно, работает на всех основных СУБД, включая PostgreSQL, MySQL, SQL Server и, что не менее важно, Oracle. Какие подводные камни следует избегать при написании переносимого SQL?

Кстати, существует ли проект, целью которого является перевод действительного подмножества SQL в конкретные диалекты, используемые всеми этими поставщиками? Я знаю, что Hibernate и другие системы ORM должны делать это, но я не хочу ORM, я хочу писать SQL прямо в базу данных.

Спасибо!

Ответы [ 5 ]

4 голосов
/ 13 апреля 2011

Проблема в том, что некоторые СУБД даже игнорируют самые простые стандарты (например, такие как символы цитирования или конкатенация строк).

Таким образом, следующее (100% ANSI SQL) не выполняется на каждой СУБД:

UPDATE some_table
    SET some_column = some_column || '_more_data';

И я даже не думаю о более продвинутых стандартах SQL, таких как рекурсивные выражения общих таблиц (дажете, которые поддерживают его, не всегда соответствуют) или функции управления окнами (некоторые реализуют только очень узкое подмножество, некоторые не поддерживают все параметры).

Что касается DDL, существует проблема с типами данных.DATE не везде одинаков, как и TIMESTAMP.Не каждая СУБД имеет тип BOOLEAN или TIME.

Когда дело касается ограничений или доменов, вы получаете еще больше различий.

Итак, в двух словах: если вы действительно, действительно должны быть независимыми от СУБД, не беспокойтесь об этом.

Сказав все это: если у вас естьПри выборе между собственным и стандартным синтаксисом выберите стандартный синтаксис (OUTER JOIN против (+) или *=, decode против CASE, nvl против coalesce и т. д.).

2 голосов
/ 13 апреля 2011

В каждой СУБД все, что указано в качестве ANSI-совместимого, должно быть одинаковым для всех из них, поскольку это настоящий стандарт.Однако, придерживаясь только ANSI (то есть переносимого) материала, вы теряете оптимизированную, специфичную для поставщика функциональность.Кроме того, то, что PostgreSQL реализует функцию ANSI, не означает, что она доступна в любой другой СУБД (но если она доступна, она должна работать так же).

Лично я не вижу значения в истиннопереносимый код SQL или проект для нормализации до набора с наименьшим общим знаменателем, поскольку каждая конкретная СУБД оптимизируется по-разному.Нет общего языка приложений.Если вы используете C #, то вы не захотите использовать вещи, которые можно найти только в PHP или JAVA.Так что просто примите платформу, на которой вы находитесь:).

Редактировать: Если вы пишете приложение, которое может подключаться к нескольким различным СУБД, вам, вероятно, потребуется найти соответствующий SQL для каждой конкретной платформы, какАвторы каждого из ORM должны были сделать.

1 голос
/ 27 июля 2013

Я создаю веб-приложения, используя Alpha Five, который имеет функцию «Portable SQL». Существует около 200 «функций переносимости». Если я использую функцию переносимости, она автоматически конвертируется в собственный SQL, чтобы соответствовать любому движку, который я использую.

Так что, если я напишу «SELECT now () FROM clients», теперь now () - функция переносимости, этот синтаксис будет автоматически преобразован в родной язык, в зависимости от того, какой случай я использую. Они поддерживают 22 различных движка SQL.

  • DB2-SELECT CURRENT TIMESTAMP AS Expr1 ОТ клиента
  • MYSQL-SELECT Now () в качестве Expr1 ОТ клиента
  • MSSQL-SELECT CURRENT_TIMESTAMP AS Expr1 ОТ клиента
  • SYBASE-SELECT getdate () AS Expr1 ОТ клиента
  • ODBC-SELECT {fn Now ()} AS Expr1 ОТ клиента
1 голос
/ 14 апреля 2011

Идеал, что я могу написать SQL-код для одного продукта и ожидать, что он будет работать на другом без изменений, - несбыточная мечта.

Я скорее считаю, что «переносимость» - это мера того, насколько легко перенести код в другой продукт SQL или, что более важно, в более позднюю версию того же продукта SQL, отмечая, что устоявшиеся продукты SQL имеют тенденцию двигаться к Стандартам SQL (например, для SQL-92 UPDATE требуются скалярные подзапросы, следовательно, он слишком длинный, SQL Server на раннем этапе предоставил собственный синтаксис JOIN..FROM, а затем для SQL Server 2008 - синтаксис MERGE, который поддерживает и расширяют стандартные SQL * MERGE).

Как правило, используйте стандартный SQL-код там, где его поддерживает ваш продукт SQL (например, CURRENT_TIMESTAMP вместо SQL Server getdate())в противном случае предпочитайте собственный код, который легко сопоставляется с кодом стандартного SQL (например, SUBSTRING() SQL Server легко сопоставляется с SUBSTRING() стандартного SQL с помощью макроса).Обратите внимание, что некоторые функции вне стандарта SQL будут общими для продуктов SQL (например, большинство / все будут иметь функцию или оператор MOD()).

1 голос
/ 13 апреля 2011

Простые запросы почти всегда переносимы. К сожалению, список поставщиков SQL, которые вы предоставили, сильно различается в соответствии стандартам. MS SQL Server занимает первое место среди тех, что вы перечислили с точки зрения соответствия стандартам ANSI SQL, и MySQL и Oracle, как известно, плохо работают, когда дело доходит до соответствия стандартам. Это, конечно, не означает, что они являются плохими движками СУБД или что вы не можете писать с ними мощные запросы, но их приверженность стандартам не совсем то, чем они известны.

Обратите внимание, что в этом списке вы не указали некоторых крупных игроков RDBMS, а именно Sybase и IBM DB2. Эти два, как правило, более совместимы со стандартами, чем другие, для чего это стоит.

...