На работе было задание перевести запросы SQL, написанные для СУБД Oracle 10g, на MS SQL Server 2008 (читай, миграция/перенос запросов SQL из Oracle в MS SQL). По ходу решил протоколировать обнаруженные расхождения. Материал данной статьи может содержать ошибки и будет отражать исключительно мое мнение (вполне вероятно - ошибочное).
В заголовке статьи я использовал термин "программист SQL", под которым имею в виду занимающегося написанием различных запросов на языке SQL человека.
Также в заголовке статьи использован термин "одностороннее сравнение", которым подчеркивается, что запросы переводились только в одну сторону, с Oracle 10g (далее Oracle) на MS SQL Server 2008 (далее MS SQL), и расхождения/разности выявлялись в одном направлении.
Итак...
- В Oracle есть функция DECODE, по-моему достаточно удобная. Её в MS SQL не оказалось. Пришлось воспользоваться оператором CASE-WHEN-THEN-ELSE-END.
- В Oracle есть функция CEIL - разновидность округления. В MS SQL та же функция называется CEILING.
- В Oracle есть Materialized View, в MS SQL этого счастья - нет. Придется создавать таблицы и продумывать DROP, INSERT, UPDATE.
- В Oracle есть функция wm_concat, которая используется для сцепления группы строковых значений. В MS SQL именно этой функции нет, но есть функция STUFF. Если вам придется искать замену wm_concat, то советую копать в сторону следующего запроса:
SELECT STUFF((SELECT ',' + Column_Name FROM Table_Name FOR XML PATH ('')), 1, 1, '')
- В Oracle был запрос, который использовал функцию FIRST_VALUE в связке с OVER и PARTITION BY. Перевод этого запроса в MS SQL превратился в настоящее приключение (и даже небольшое исследование). В MS SQL Server 2008 функции FIRST_VALUE нет, но будет в MS SQL Server 2012. В итоге, аналог упомянутого запроса создал с использованием CTE (Common Table Expressions) With, OVER, PARTITION BY и функции RANK.
- Oracle NVL = MS SQL ISNULL
- В Oracle есть возможность использования оператора IN c несколькими полями (multi-column IN statement):
SELECT * FROM
В MS SQL можно использовать IN только с одним полем. Эмуляцию оператора IN c несколькими полями можно сделать с помощью оператора INNER JOIN:WHERE (column1, column2, ..., columnN) IN ( SELECT DISTINCT column1, column2, ..., columnN FROM WHERE ) [AND ...] SELECT * FROM
T1 INNER JOIN ( SELECT DISTINCT column1, column2, ..., columnN FROM WHERE ) T2 ON T1.column1 = T2.column1 AND T1.column2 = T2.column2 ... AND T1.columnN = T2.columnN WHERE - Для извлечения даты из типа datetime в MS SQL можно использовать CAST(datetime_value as DATE) или CONVERT(DATE, datetime_value), которые являются аналогами Oracle TRUNC(datetime_value).