Простой SQL против диалектов - PullRequest
3 голосов
/ 08 января 2010

Поставщики СУБД используют возможности диалекта SQL для дифференциации своего продукта, одновременно утверждая, что поддерживают стандарты SQL. «Нуфф сказал об этом.

Есть ли какой-нибудь пример SQL, который вы кодировали, который не может быть переведен в SQL: стандартный SQL 2008?

Если говорить точнее, я говорю о DML (оператор запроса), НЕ DDL, синтаксисе хранимых процедур или о чем-то, что не является чисто SQL-оператором.

Я также говорю о запросах, которые вы будете использовать в Production, а не для специальных вещей.

Редактировать 13 января

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

Ответы [ 5 ]

3 голосов
/ 08 января 2010

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

Можно использовать ANSI SQL по большей части в системах баз данных и ожидать получения разумных результатов набаза данных без существенных проблем настройки, таких как отсутствующие индексы.Тем не менее, в любом нетривиальном приложении, вероятно, существует некоторое требование к коду, который не может быть легко выполнен переносимым.

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

Следовательно, маловероятно, что использование «переносимых» конструкций SQL для приложения будет работать в общем случае.Лучшая стратегия состоит в том, чтобы использовать общие операторы, где они будут работать, и переходить на уровень, специфичный для базы данных, где это не работает.

Общий механизм запросов мог бы заключаться в использовании ANSI SQL, где это возможно;Другой возможный подход заключается в использовании O / R Mapper, который может принимать драйверы для различных платформ баз данных.Механизм такого типа должен подойти для большинства операций с базой данных, но потребует от вас выполнения определенной работы, связанной с платформой, когда она исчерпывается.

Возможно, вы сможете использовать хранимые процедуры в качестве уровня абстракции для большегосложные операции и кодирование набора специфичных для платформы sprocs для каждой целевой платформы.Доступ к sprocs можно получить через что-то вроде ADO.net.

На практике тонкие различия в передаче параметров и обработке исключений могут вызвать проблемы с этим подходом.Лучшим подходом является создание модуля, объединяющего операции базы данных для платформы с общим интерфейсом.В зависимости от используемой вами платформы СУБД можно менять и вставлять разные модули драйверов.

3 голосов
/ 08 января 2010

Oracle имеет некоторые дополнения, такие как модель или иерархические запросы, которые очень трудно, если не невозможно, перевести на чистый SQL

1 голос
/ 08 января 2010

Распространено здесь на SO

Чтобы ответить точно:

ISNULL может легко выдавать разные результаты как COALESCE на SQL Server из-за приоритета типа данных, согласно моему ответу / комментариям здесь

1 голос
/ 08 января 2010

Даже когда SQL: 2008 может что-то делать, иногда синтаксис не тот. Возьмите синтаксис соответствия REGEXP, например, SQL: 2008 использует LIKE_REGEX против MySQL REGEXP.

И да, я согласен, это очень раздражает.

1 голос
/ 08 января 2010

Часть проблемы с Oracle заключается в том, что он по-прежнему основан на стандарте SQL 1992 ANSI. SQL Server соответствует стандарту SQL 1999, поэтому некоторые вещи, которые выглядят как «расширения», на самом деле являются более новыми стандартами. (Я считаю, что предложение "OVER" является одним из них.)

Oracle также гораздо более ограничен в размещении подзапросов в SQL. SQL Server гораздо гибче и позволяет использовать подзапросы практически везде.

В SQL Server есть рациональный способ выбрать «верхнюю» строку результата: «ВЫБЕРИТЕ ТОП 1 ОТ ЗАКАЗЧИКА ПО ЗАКАЗУ SALES_TOTAL». В Oracle это становится «ВЫБРАТЬ * ИЗ (ВЫБРАТЬ ЗАКАЗЧИКОВ ПО ЗАКАЗУ SALES_TOTAL) ГДЕ ROW_NUMBER <= 1». </p>

И, конечно, в Oracle всегда есть печально известный SELECT (выражение) FROM DUAL.

Изменить, чтобы добавить:

Теперь, когда я на работе и могу получить доступ к некоторым из моих примеров, вот хороший. Это генерируется LINQ-to-SQL, но это чистый запрос для выбора строк 41–50 из таблицы после сортировки. Используется предложение «OVER»:

SELECT [t1].[CustomerID], [t1].[CompanyName], [t1].[ContactName], [t1].[ContactTitle], [t1].[Address], [t1].[City], [t1].[Region], [t1].[PostalCode], [t1].[Country], [t1].[Phone], [t1].[Fax]
    FROM (
        SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ContactName]) AS [ROW_NUMBER], [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax]
        FROM [dbo].[Customers] AS [t0]
        ) AS [t1]
    WHERE [t1].[ROW_NUMBER] BETWEEN 40 + 1 AND 40 + 10
    ORDER BY [t1].[ROW_NUMBER]
...