Документация Firebird → Документация по Firebird → Переход с MS SQL на Firebird → Синтакс SQL |
Этот раздел описывает основные различия в синтаксе языка SQL, используемого СУБД Firebird и MS SQL.
СУБД Firebird и MS SQL могут ссылаться на объекты базы данных (таблицы, поля и т.д.) по их именам напрямую, если имена объектов не содержат пробелы и другие недопустимые в прямой ссылке символы (например, нелатинские буквы). Для использования пробелов и других символов СУБД MS SQL использует квадратные скобки, [ и ], а СУБД Firebird использует двойные кавычки, ". Еще одно различие - возможность использования в СУБД MS SQL схемы для ссылки на объект: база_данных.владелец_объекта.объект. СУБД Firebird не допускает такой нотации.
СУБД MS SQL использует регистро-зависимые имена объектов, если при установке Вы выбрали использование различения регистра символов; в противном случае, имена объектов регистро-независимы. Весело? Не очень...
СУБД MS SQL способна работать с идентификаторами, имена которых заключены в двойные кавычки, но по умолчанию эта возможность доступна только при доступе через OLE DB и ODBC, но не при доступе через DB-Library. По этой причине такую практику работы следует избегать.
СУБД MS SQL 7 и выше поддерживает обновляемые соединения (joins) (обновление, удаление, вставка). СУБД Firebird не распознает такой синтакс.
Типы даных, конечно, различаются. Хотя обе СУБД имеют общее подмножество наиболее часто используемых типов. Этот вопрос редко вызывает проблемы при переносе базы данных.
Различаются встроенные функции. Большинство из встроенных функций СУБД MS SQL можно заменить в СУБД Firebird использованием функций, определяемых пользователем (UDFs).
Различаются форматы указания строковых констант для дат. СУБД Firebird принимает строки различных форматов, вне зависимости от используемой платформы. СУБД MS SQL, в свою очередь, использует совмещение серверо-независимых, серверо-платформенных форматов и формата настройки клиентского соединения. Дополнительно, методы доступа СУБД MS SQL обычно вводят один или два уровня, в которых строковая константа может быть преобразована в дату тем или иным образом.
В СУБД MS SQL можно определять бОльшее количество переменных окружения, чем в СУБД Firebird, но наиболее общие можно найти и в СУБД Firebird (извлечение идентификатора и имени пользователя). Единственная важная переменная, которая отсутствует в СУБД Firebird, - это переменная, возвращающая количество строк последней операции (с версии 1.5 СУБД Firebird такая переменная введена - прим. перев.).
Важное различие было в том, что СУБД Firebird 1.0 не поддерживала оператор CASE СУБД MS SQL. Иногда можно было заменить его функциональность использованием хранимой процедуры. Начиная с версии 1.5, СУБД Firebird поддерживает использование оператора CASE.
Небольшое различие между СУБД еще и в том, что СУБД MS SQL не использует разделителей для операторов, что может служить источником трудно обнаруживаемых ошибок при переходе, особенно при использовании множества скобок. СУБД Firebird в скриптах требует завершать каждый оператор точкой с запятой (если не определен другой разделитель - прим. перев.), поэтому ошибки легче обнаружить.
Обе СУБД MS SQL и Firebird поддерживают комментарии, заключенные между разделителями /* и */. СУБД MS SQL также поддерживает синтакс «два дефиса» -- для однострочного комментария. Некоторые утилиты для СУБД Firebird также поддерживают такой синтакс.
СУБД MS SQL позволяет клиентам обращаться к нескольким базам данных через одно и то же соединение. Для этого при обращении к объектам баз данных необходимо использовать нотацию база_данных.владелец_объекта.объект, либо явно использовать оператор USE.
СУБД Firebird не допускает использование нескольких баз данных в одном операторе SQL. Однако эта СУБД позволяет клиенту работать с транзакциями, охватывающими несколько баз данных.
Существует много утилит для ввода и выполнения операторов SQL для обоих платформ. Имейте в виду, что для СУБД Firebird не нужно вводить команду GO для разделения пакетов команд, как для пакетов T-SQL - Вы обычно управляете транзакциями явно. Также, Вы можете для обоих СУБД использовать настройку «подтверждать (commit) каждый оператор».
Если Вы установили СУБД MS SQL и Firebird на один компьютер, будьте внимательны при использовании утилиты isql. Если Вы не указываете при запуске этой утилиты полный путь, будет запущена та, что первой будет найдена по путям для поиска файлов, а обе СУБД имеют в своем составе программу с именем isql.
Управление переменными схоже на обоих платформах. Переменные необходимо объявлять до их использования, а также указать их тип. В СУБД Firebird нет необходимости добавлять к имени переменной префикс @, а также переменные обязательно должны быть объявлены до тела хранимой процедуры или триггера.
Например, сравните следующие части кода.
/* MS-SQL */ CREATE PROCEDURE my_procedure AS DECLARE @my_variable int SET @my_variable = 5
/* Firebird */ CREATE PROCEDURE my_procedure AS DECLARE VARIABLE my_variable int; BEGIN my_variable = 5; END
В обоих СУБД параметры считаются обычными переменными с установленным начальным значением.
В обоих СУБД ключевые слова BEGIN и END могут использоваться для объединения нескольких операторов в один блок, например, при использовании в условном операторе IF.
СУБД Firebird не имеет оператора GOTO. Однако, как правило, это к лучшему. Оператор GOTO обычно используется СУБД MS SQL, потому что по умолчанию возникающие при выполнении операторов ошибки не откатывают транзакции, необходимо после выполнения каждого оператора проверять значение переменной @@ERROR; оператор GOTO используется для объединения в группы операторов управления ошибками. В СУБД Firebird используется более удачный механизм управления ошибками - оператор WHEN...DO.
Конечно, оператор GOTO может использоваться и для других целей. В таком случае, правильное использование хранимых процедур обычно улучшает дизайн базы данных.
Оператор IF..ELSE в СУБД Firebird имеет ту же семантику, что и в СУБД MS SQL, однако синтакс СУБД Firebird требует наличия ключевого слова THEN после условия.
IF (something = 'unknown') THEN something = 'uuhhh.....'; ELSE something = 'I know! I know!';
СУБД Firebird 1.0 не поддерживает оператор CASE, поэтому Вам необходимо будет сделать дополнительную работу по переносу, если Вы использовали этот оператор в базе данных СУБД MS-SQL.
Вы можете пропустить этот раздел, если Вы используете СУБД Firebird 1.5 или более новую версию, так как, начиная с версии 1.5, СУБД Firebird имеет поддержку оператора CASE.
Оператор CASE используется аналогично оператору switch языка C или оператору case языка Pascal для замены одного значения на другое. Обычно в СУБД Firebird 1.0 эту операцию можно эмулировать хранимой процедурой, возвращающей некоторое значение.
/* Это исходный оператор MS SQL, использующий традиционную базу данных pubs. */ CREATE PROCEDURE list_states AS SELECT CASE state WHEN 'CA' THEN 'California' WHEN 'UT' THEN 'Utah' ELSE 'unknown' END FROM authors
/* Это вариант перевода в СУБД Firebird 1.0. */ /* Выделить оператор CASE. */ CREATE PROCEDURE get_state_name ( state_code char(2) ) RETURNS ( state_name varchar(64) ) AS BEGIN IF (state_code = 'CA') THEN state_name = 'California'; ELSE IF (state_code = 'UT') THEN state_name = 'Utah'; ELSE state_name = 'unknown'; END /* Это процедура-выборка. */ CREATE PROCEDURE list_states RETURNS (state varchar(64)) AS DECLARE VARIABLE short_state CHAR(2); BEGIN FOR SELECT state FROM authors INTO :short_state DO BEGIN EXECUTE PROCEDURE get_state_name :short_state RETURNING_VALUES :state; SUSPEND; END END
Три замечания по приведенному примеру. Во-первых, перенос является тривиальным. Во-вторых, текст получается довольно ясным. В-третьих, использование хранимой процедуры вносит бОльшую гибкость и простоту внесения изменений логики. Предположим, оператор CASE для поля state встречается в 12 различных процедурах, и был добавлен новый штат, или что Вы неправильно написали название штата... Совершенно ясно, что лучше выполнить указанное преобразование для использования хранимой процедуры.
Еще раз: с версии 1.5 СУБД Firebird полностью поддерживает оператор CASE, поэтому, в принципе, необходимости перехода на использование хранимых процедур нет.
Оператор WHILE существует в обоих СУБД Firebird и MS SQL, но с некоторыми различиями. Не существует операторов BREAK или CONTINUE, но их можно эмулировать при помощи дополнительных конструкций. Так же есть небольшое различие в используемом синтаксисе: СУБД Firebird требует наличия ключевого слова DO после условия цикла. Сравните следующие эквивалентные части кода.
/* Синтакс Firebird. */ WHILE (i < 3) DO BEGIN i = i + 1; j = j * 2; END
/* Синтакс MS SQL. */ WHILE (i < 3) BEGIN SET @i = @i + 1 SET @j = @j * 2 END
Оператор RETURN в СУБД MS SQL возвращает значение целочисленной переменной и прекращает выполнение. В СУБД Firebird существует оператор EXIT, который передает управление на заключительный END хранимой процедуры. Однако здесь нет скрытой возвращаемой переменной, поэтому, если Вам необходимо вернуть некоторое значение (что опционально в СУБД MS SQL), Вы должны явно объявить возвращаемую переменную в процедуре.
Оператор WAITFOR в СУБД MS SQL приостанавливает выполнение на некоторое время или до наступления указанного времени. Что-то подобное можно осуществить при помощи функций, определяемых пользователем (UDFs), в СУБД Firebird. Но в обоих СУБД использование такого оператора следует исключить, поскольку взаимодействие с клиентом полностью приостанавливается (в СУБД Firebird это может привести и к приостановке обслуживания всех соединений, а не только соединения, вызвавшего аналог указанного оператора - прим. перев.).
Стандартными операторами, имеющимися в обоих СУБД, являются SELECT, INSERT, UPDATE и DELETE. СУБД Firebird и MS SQL поддерживают их, но в СУБД MS SQL есть несколько нестандартных расширений этих операторов, о которых необходимо рассказать на случай их использования.
В СУБД Firebird оператор SELECT не позволяет использовать ключевое слово INTO для создания новой таблицы «на лету». Вместо этого, ключевое слово INTO используется для связи результата запроса с переменной.
/* Синтаксис MS SQL для присваивания значения поля переменной. */ SELECT @my_state = state FROM authors WHERE auth_name = 'John'
/* Синтаксис Firebird. */ SELECT state INTO :state /* --> обратите внимание на ":" перед именем переменной */ FROM authors WHERE auth_name = 'John'
В СУБД MS SQL 7 и выше в операторе SELECT можно указвать спецификатор TOP для органичения возвращаемого набора данных. Эта функция в настоящий момент находится в стадии разработки для СУБД Firebird. (Спецификаторы FIRST и SKIP в СУБД Firebird введены, начиная с версии 1.5. - прим. перев.)
Обе СУБД MS SQL и Firebird поддерживают обычный синтаксис оператора INSERT и оператора INSERT..SELECT.
Обе СУБД MS SQL и Firebird поддерживают обычный синтаксис оператора UPDATE. СУБД MS SQL также поддерживает синтаксис оператора UPDATE, в котором выполняется соединение (join) и производится обновление одной из таблиц соединения. Можно думать об этом как об условии WHERE на стероидах. Если такая функция очень нужна, то ее можно реализовать в СУБД Firebird с использованием представлений (views).
Обе СУБД MS SQL и Firebird поддерживают обычный синтаксис оператора DELETE. СУБД MS SQL также поддерживает оператор TRUNCATE TABLE, который более эффективен (но и опаснее), чем оператор DELETE. (СУБД MS SQL также поддерживает синтаксис оператора DELETE, в котором выполняется соединение. - прим. перев.)
/* Синтаксис MS SQL для удаления всех записей my_table. */ TRUNCATE TABLE my_table /* ...или... */ DELETE FROM my_table
/* Синтаксис Firebird. */ DELETE FROM my_table
Самая большая угроза - действовать «методом тыка». Больше всего данных было утеряно командами "delete from xxx" и последующей "ой!", чем продуманной командой "delete from rdb$pages". |
||
--Jim Starkey |
В СУБД Firebird в DSQL (dynamic SQL) транзакции «напрямую» не используются. Именованные транзакции в этом случае недоступны совсем. (Операторы DSQL выполняются в контексте транзакций, запущенных и контролируемых клиентским приложением.- прим. перев.) Синтаксис обоих СУБД поддерживает ключевое слово WORK для совместимости.
В большинстве случаев проблем с транзакциями не должно возникать: явное управление транзакциями «на месте» в СУБД MS SQL используется обычно из-за отсутствия поддержки управлением через исключения (exceptions).
В СУБД MS SQL есть глобальная переменная XACT_ABORT, которая управляет откатом транзакции при возникновении ошибки времени выполнения (run-time error). В противном случае Вам необходимо проверять значение переменной @@ERROR после выполнения каждого оператора.
В общем, большинство проблем, связанных с уровнями изоляции транзакций в СУБД MS SQL, пропадают при переходе на СУБД Firebird. Соперничество между «читателями» и «писателями» минимально за счет использования многоверсионной архитектуры (multigeneration architecture, MGA).
В СУБД MS SQL курсоры используются, в основном, для перемещения по результатам запросов, чтобы выполнить с этими результатами некоторые действия. Кроме синтаксиса, нет большой разницы для выполнения одной и той же задачи. Хотя существуют опции для перемещения вперед и назад, на практике используются, по большей части, однонаправленные курсоры.
/* Синтакс MS SQL. */ DECLARE my_cursor CURSOR FOR SELECT au_lname FROM authors ORDER BY au_lname DECLARE @au_lname varchar(40) OPEN my_cursor FETCH NEXT FROM my_cursor INTO @au_lname WHILE @@FETCH_STATUS = 0 BEGIN /* Сделать что-то интересное с @au_lname. */ FETCH NEXT FROM my_cursor END CLOSE my_cursor DEALLOCATE my_cursor
/* Синтакс Firebird. */ DECLARE VARIABLE au_lname VARCHAR(40); ... FOR SELECT au_lname FROM authors ORDER BY au_lname INTO :au_lname DO BEGIN /* Сделать что-то интересное с au_lname. */ END
Заметьте, что СУБД MS SQL может размещать курсоры в переменных, и передавать эти переменные как параметры; это невозможно в СУБД Firebird.
Различные версии СУБД MS SQL имеют различные области видимости для переменных-курсоров. Будьте осторожны при их использовании и при переносе кода.
Документация Firebird → Документация по Firebird → Переход с MS SQL на Firebird → Синтакс SQL |