Упрощенное руководство по переходу с диалекта 1 (IB 4.x и 5.x) на диалект 3 (IB 6.x/7.x, Firebird)

Кузьменко Дмитрий, 06.09.2000, последнее обновление – 16.01.2008.

Разумеется, существует официальный документ (Migration Guide), в котором описан процесс перехода. Там все изложено весьма подробно, что как раз и мешает быстрому освоению процесса перехода на новый сервер. Здесь предлагается практический подход к переходу на третий диалект (диалект 3, появившийся в InterBase 6.0), что, правда, никоим образом не отменяет необходимость чтения Migration Guide.

В последний момент перед выпуском релиза IB 6 в него была встроена возможность поддержки формата ODS9, т.е. формата баз данных IB 5.x. Поэтому бета-версия 6.0 не может работать со старыми базами данных, а релиз 6.0 – может. Однако при переходе даже между minor версиями (например переход с 5.5 на 5.6) все равно рекомендуется сделать backup/restore. Более того, код view, процедур и триггеров (и других объектов) хранился в базе данных в виде Binary Language Representation (BLR) версии 4 в базах данных IB 5.x. А IB 6.0 использует для тех же целей BLR версии 5. Поэтому если вдруг вы измените или создадите какой-то объект в старой БД из под IB 6.0, то впоследствии может обнаружиться, что эта же база данных уже "не читается" в IB 5.x. Поэтому я ни в коем случае не рекомендую работать со старыми БД из IB 6.
 
Внимание! В триалах платных версий 6.0.1 6 и 6.5 возможность работы с базами ODS9 исключена.

Документ старый, поэтому везде, где упоминается IB 6, может быть использован Firebird 1.x, InterBase 7.x, Yaffil и т.д.

Использовать InterBase 6.0 в настоящее время крайне не рекомендуется. Эта версия сервера слишком устарела.
 

Самый простой вариант

Чтобы не мучить читателя, приведу самый быстрый вариант перехода с 5.x на 6:
  1. backup всех баз данных под сервером 5.x (на всякий случай рекомендуется проверить их restore, или просто откопировать на ленту или CD-ROM)
  2. деинсталляция IB 5
  3. установка IB 6
  4. restore баз данных
Все. После этих операций сервер будет работать точно так же (почти) как и сервер 5.x. Однако перенесенная база данных не получит никаких возможностей IB 6, т. е. будет иметь диалект 1 (совместимость с 5.x).

Сразу надо сказать, что совместимость будет неполная. То есть, тут же, в 1-ом диалекте, но на новой версии сервера, если в базе есть объекты, поименованные новыми ключевыми словами (YEAR, MONTH и т.п., см. дальше), будут конфликты с существующими запросами.

Дальнейшие попытки перевести базу данных из диалекта 1 в диалект 3 могут оказаться сложными, поэтому лучше всего заранее подготовить базу данных еще под сервером 5.x.
 
Примечание. Возможные проблемы после установки IB 6 могут появиться, если вы устанавливаете IB 6 поверх IB любой из предыдущих версий. IB принято всегда деинсталлировать перед установкой даже промежуточных версий (например с 5.5 на 5.6). Причем нужно помнить следующее: IB при деинсталляции не удаляет несколько файлов в своем основном каталоге, и одним из них является база данных пользователей – ISC4.GDB. При установке IB проверяет, нет ли этого файла в каталоге, куда он устанавливается, и если есть – не переписывает его. Если при последовательном увеличении версий (с 4.x до 5.6) наличие старых версий ISC4.GDB не приводило к каким либо проблемам (IB 5.x умеет работать с базами данных 4.x), то при переходе на 6 старый isc4.gdb может вызвать проблемы. Проявляться это будет как сообщение "Can not attach to password database" при попытке подсоединения к серверу. Если на компьютере разработчика обычно пользователей кроме SYSDBA нет, то на промышленном сервере может быть большое количество пользователей в ISC4.GDB. Эту базу данных надо сохранить (backup) точно так же, как и все остальные перед установкой IB6, например в isc4copy.gbk. Затем, установив IB6 (предварительно убедившись что isc4.gdb удален), произвести restore isc4copy.gbk в isc4copy.gdb. Потом нужно остановить сервер IB6, удалить isc4.gdb и переименовать isc4copy.gdb в isc4.gdb. Если же пользователи не нужны, то в случае указанной выше проблемы можно просто переписать isc4.gdb из дистрибутива IB6.
 

Назад пути не будет

Разумеется, перейти обратно, т.е. с 6.0 на 5.x, можно. Делается это при наличии двух серверов с установленными IB 5 и IB 6 соответственно. Из IB 5 (Server Manager) вы даете "указание" серверу IB 6 сделать backup на сервер IB 5, и в результате получаете backup, который можно восстановить на 5.x (backup от 6.0 не восстановится на сервере 5.x). Эта операция подробно описана в документе.

Но даже если вы решились перенести вашу базу данных под IB 6 в диалект 1, помните, что диалект 1 является устаревшим, и вполне может оказаться что последующие версии IB или FB поддерживать этот диалект не будут. Пока таких угроз разработчики FB или IB не делают, но все может случиться. Таким образом, если решились перейти с IB 4/5 на новые версии IB/FB с диалектом 1, то в любом случае стоит запланировать перейти на диалект 3. А вот с диалекта 3 уже сделать backup для 5.x будет невозможно. Фактически, переходя на этот диалект вы обретаете все новые возможности версии 6, но сжигаете мосты для отступления на "старую, добрую" версию 5.6.
 

Подготовка

Подготовительные действия не требуют наличия IB 6/FB вообще. Дело в том, что самым основным препятствием к переходу в диалект 3 является обрамление строковых констант двойными кавычками.

Строка в двойных кавычках в диалекте 3 рассматривается как идентификатор. Грубо говоря, в диалекте 3 можно создать таблицу вот так:
CREATE TABLE "My CoOl TaBlE" ("My vARIABLE" INTEGER);
И при этом запрос к такой таблице должен быть
SELECT "My vARIABLE" from "My CoOl TaBlE";
Разумеется, это относится и к строковым константам в WHERE, к триггерам, процедурам и т. п. Поэтому первое, с чего надо начать, это убрать двойные кавычки отовсюду.
 
Внимание! Рекомендуется при работе в инструментах типа IBExpert или QuickDesk включить опцию, которая безусловно переводит имена объектов при их создании к верхнему регистру. Так вам не нужно будет следить за регистром имен объектов при написании запросов, и указывать эти имена в двойных кавычках. Например в IBExpert это опция меню Database Properties/General – always capitalaise object names (по умолчанию включено в последних версиях). То есть, при создании любых объектов их имена будут автоматически переводиться в верхний регистр. Это нормально, и сэкономит вам массу времени (в том числе и зрение) по причине отсутствия мучений с "" и точным соблюдением регистра букв в именах объектов. Также последствия использования двойных кавычек более подробно описаны в FAQ.

Клиент-серверная архитектура состоит из двух частей: клиента и сервера. Большинство, наверное, работают на Delphi, поэтому замена двойных кавычек в запросах на одинарные вызовет некоторые проблемы, если SQL-операторы зашиты в коде (а не в свойствах компонент). Однако, особых проблем здесь тоже нет:
'SELECT FIELD FROM MYTABLE WHERE FIELD2 STARTING WITH "A"'
заменяется на
'SELECT FIELD FROM MYTABLE WHERE FIELD2 STARTING WITH ''A''';
Обратите внимание  в конце строки перед A две одинарные кавычки, а после A  три.

В общем, Search/Find in files вам поможет.

С базой данных можно сделать то же самое. Двойные кавычки могут быть: в запросах во view, в триггерах и в процедурах. Их можно обнаружить так: (containing кавычка, двойная кавычка, кавычка)
view:
SELECT RDB$RELATION_NAME FROM RDB$RELATIONS
WHERE RDB$VIEW_SOURCE CONTAINING '"';
triggers:
SELECT RDB$TRIGGER_NAME FROM RDB$RIGGERS
WHERE RDB$TRIGGER_SOURCE CONTAINING '"';
procedures:
SELECT RDB$PROCEDURE_NAME FROM RDB$PROCEDURES
WHERE RDB$PROCEDURE_SOURCE CONTAINING '"';

Правда, если вы в тексте этих объектов использовали двойные кавычки для слов в комментариях, то эти объекты тоже попадут в список "подозрительных".

Надо сказать, что даже если вы не сделаете замены двойных кавычек на одинарные, то все равно view, триггеры и процедуры будут продолжать работать. Дело в том, что IB хранит текст этих объектов только для его возможной модификации. После создания объекта он хранится в виде скомпилированного кода (BLR), и именно так вызывается при обращении к объекту. А в BLR никаких кавычек для имен объектов и для строк нет вообще. Т. е. строка хранится как char в любом компиляторе. Т. е. работать view, триггеры и процедуры будут, а если вы попробуете их изменить, и в тексте есть двойные кавычки для строк, то будет выдана ошибка.

Кроме убирания двойных кавычек стоит еще заранее запастись инструментами, которые поддерживают IB 6, например ib_isql или другими. Помните, что привычные вам средства могут поддерживать только диалект 1 (например, Database Explorer), и с диалектом 3 эти инструменты полноценно работать не будут. IBConsole может оказаться непривычным инструментом (и некачественным), поэтому стоит попробовать альтернативы заранее.
 

Проверка

После того, как убраны все двойные кавычки, стоит заняться установкой IB 6. Но, на другой компьютер. Не стоит ломать свою работу, если вдруг под IB 6 у вас что-то пойдет не так. На компьютере разработчика можно сделать backup всех баз данных под 5.x, деинсталлировать 5.x, установить 6.0 и восстановить все (или только нужные) базы данных.

Для проверки переносимости базы данных следует извлечь из нее полный скрипт метаданных. Вполне подойдет WISQL, а другими средствами пользоваться не стоит, т.к. они могут вывести скрипт не совсем так, как это нужно isql, или с ошибками. Получаем скрипт:
isql f:\base.gdb -x -o base1.ddl

Правда, WISQL/isql сам с большой степенью упрямства выводит в скрипт декларацию функций, возвращающих BLOB-поля, как возвращающие BLOB BY VALUE. Это не соответствует реальному объявлению функции, и IB будет ругаться при импорте скрипта. Поэтому сразу после экспорта скрипта БД стоит проверить его на наличие "blob by value" и заменить ее на "blob".
 
Примечание. Приведенная команда isql будет работать только в том случае, если Interbase запущен как приложение (application), а не как сервис (service). Вообще мне не удалось выполнить такую команду при работе IB сервисом, кроме как созданием системных (а не пользовательских) переменных окружения ISC_USER и ISC_PASSWORD и присвоения им соответствующих значений. Очевидно, присутствует какой-то баг isql, или в документации неверно описаны команды isql для указания имени пользователя и пароля. При этом я настоятельно не советую пользоваться IBConsole из бета-версии IB6 – она (консоль) содержит ряд ошибок, которые в том числе касаются выводимого скрипта метаданных.

Таким образом, получается, что извлечь скрипт с помощью isql можно, когда вы сидите за компьютером, на котором IB запущен как приложение. Или когда IB запущен как сервис, но созданы вышеуказанные системные переменные (для NT в MyComputer/Properties/Environment, раздел System variables). Можно их не создавать, а установить в cmd-файле, написав до вызова isql команды set ISC_USER=SYSDBA и т. п.

После этого можно приступать к проверке скрипта на переносимость. Для этого в самом начале скрипта base1.ddl следует написать
SET SQL DIALECT 2;

Диалект 2 в IB 6 предназначен для проверки переносимости баз данных из диалекта 1 в диалект 3. При запуске такого скрипта isql будет выводить массу предупреждающих сообщений там, где он заметит несовместимость или другие несоответствия текущего скрипта для диалекта 3.
 
Примечание. Не забудьте в начале скрипта (перед connect или create database) написать SET NAMES WIN1251;, если текст скрипта содержит комментарии или строковые константы на русском языке, а в базе данных установлен CHARACTER SET как WIN1251.

Также для удобства проверки стоит изменить имя создаваемой базы данных на что-нибудь вроде "2.gdb", и не забыть раскомментировать команду create database (и поставить после нее точку с запятой). Даже в диалекте 2 база данных все равно будет создаваться при выполнении скрипта, и вам придется для повторной проверки периодически ее удалять. Хотя можно в скрипте перед create database написать
connect 'f:\2.gdb';
drop database.

Параллельно со скриптом стоит завести текстовый файл, в который вы будете помещать исправленные конструкции DDL, для того чтобы применить их к существующей базе данных диалекта 1. Если данные вас не интересуют, и достаточно будет пустой базы данных диалекта, созданной из скрипта, то такой файл не понадобится.

Причем, проще извлекать скрипт из базы данных уже перенесенной под IB 6. Потому что все поля типа DATE будут автоматически выводиться в скрипте как TIMESTAMP. При этом легче понять, стоит оставить эти поля как TIMESTAMP (дата и время), или их следует заменить на поля DATE (только дата). Однако сразу замечу, что в данной процедуре перехода нужно только исправлять те места, где isql выдал предупреждения. Пока никаких действий по изменению типов данных делать не стоит, если мы собираемся переносить существующую базу данных, а не только ее структуру.

Делаем пробный запуск:
isql -i base1.ddl -o 2.ddl -m
ключ -i – входной файл скрипта; ключ -o – выходной файл сообщений; ключ -m заставляет isql выводить сообщения об ошибках в выходной файл сообщений.

Итак, смотрим файл 2.ddl. Для тестирования мне попалась база данных, где в вычисляемых полях используются хранимые процедуры (это не моя база данных, и вообще я считаю что такие вычисляемые поля делать нехорошо). Однако isql выводит в скрипте сначала таблицы, и только потом – процедуры. Поэтому первый запуск прошел впустую – ни одна таблица, в которой были такие вычисляемые поля, не была создана. Данную ситуацию легко исправить, поскольку isql для разрешения проблемы вложенных вызовов использует "раннее объявление" процедур, создавая процедуру пустой по create procedure, а потом выводя в скрипт полную конструкцию alter procedure. Так что остается для нужных процедур перенести перед таблицами только часть create procedure.

Перезапускаем обработку скрипта, и смотрим на ошибки:
Dynamic SQL Error
-SQL error code = -104
-Token unknown
- line 10, char 16 -Second

Первая проблема – использование в качестве имен объектов (таблиц, полей, процедур, переменных) зарезервированных слов, которые появились в IB 6. Их немного, но испортить радость перехода в третий диалект они могут:
COLUMN, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DAY, EXTRACT, HOUR, MINUTE, MONTH, SECOND TIME, TIMESTAMP, TYPE, WEEKDAY, YEAR, YEARDAY.
 
Внимание! К этим словам можно добавить CURRENT_USER и другие. См. список зарезервированных слов.

Обойти эту проблему можно двумя способами:
  1. изменить имена, совпадающие с ключевыми словами, на другие. Например, second на sec или second1.
  2. обрамить имена, совпадающие с ключевыми словами, в двойные кавычки. Было second, стало "second".

Второй способ хуже по нескольким причинам: имена объектов в двойных кавычках чувствительны к регистру. Т.е. "second" и "SECOND" – не одно и то же. Это может внести в процесс работы и отладки много неприятных минут. Вторая причина – в приложениях эти имена объектов также придется указывать в кавычках.

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

Смотрим дальше:
Dynamic SQL Error
-SQL error code = -104
-DATE must be changed to TIMESTAMP

Это сообщение появляется, когда isql встречает объявления переменных типа DATE в процедурах и триггерах. Если тип DATE для полей таблиц и параметров процедур меняется автоматически на TIMESTAMP уже при переходе в диалект 3, то переменные почему то остаются старого типа. Если предположить, что мы пока не собираемся использовать типы DATE и TIME диалекта 3, то можно просто изменить DATE на TIMESTAMP по всему скрипту поиском и заменой (не забудьте про пробелы перед и после слова DATE, иначе поиск-замена может натворить чего-нибудь лишнего).

Периодически в выводе может появляться сообщение
Use of add expression that returns different results in dialect 1 and dialect 3
или
Use of multiply expression that returns different results in dialect 1 and dialect 3

Это относится к иному поведению операций сложения/вычитания и умножения/деления в диалектах 1 и 3.

Например, допустим, в базе данных есть процедура
CREATE PROCEDURE exact1 (a INTEGER, b INTEGER)
RETURNS (c INTEGER)
AS
BEGIN
c =a / b;
SUSPEND;
END;

Если эта процедура не модифицировалась при переходе из диалекта 1 в диалект 3, или она была создана в базе данных диалекта 3 клиентом диалекта 1, то выполнение
SELECT * FROM EXACT1 ( 2, 3 )
вернет значение 1.

Если эта процедура была создана клиентом диалекта 3, то при работе из диалектов 1 или 3 она вернет значение 0. Это объясняется более простым примером: команда
SELECT 2 / 3 FROM RDB$DATABASE
в диалекте 1 возвращает 0.666666666..., а в диалекте 3 вернет 0. Т. е. диалект 1 по умолчанию предполагает результат в виде вещественного числа, а диалект 3 – в виде целого числа. Если в диалекте 3 нужно добиться поведения, аналогичного диалекту 1, то придется использовать вещественные числа:
select cast(2 as double precision) / cast(3 as double precision) from rdb$database
Такая команда вернет 0.6666666... и в диалекте 1, и в диалекте 3.

Еще один пример с умножением:
CREATE PROCEDURE bignum (a INTEGER, b INTEGER)
RETURNS (c NUMERIC(15,0)
AS
BEGIN
c =a * b;
SUSPEND;
END;
Поскольку NUMERIC(15, 0) хранится в диалекте 1 как DOUBLE PRECISION, а в диалекте 3 – как INT64, то результат тоже будет отличаться.

Если эта процедура была создана в диалекте 1, то вызов
SELECT * FROM BIGNUM (65535, 65535)
выдаст –131071.0000 как при вызове из диалекта 1, так и из диалекта 3. Но если процедура была создана или изменена в диалекте 3, то ее выполнение из диалекта 1 вернет ошибку, говорящую о том, что числа INT64 недоступны в диалекте 1. А в случае вызова из диалекта 3 будет возвращено 4294836225.

К сожалению, предупреждающие сообщения выводятся после текста процедур и триггеров, а не в том месте, где isql обнаружил операцию, которая может вызвать проблемы. Поэтому вам придется самостоятельно догадываться о местах с возможными проблемами в вычислениях.

Смотрим 2.ddl дальше:
WARNING: NUMERIC and DECIMAL fields with precision 10 or greater are stored
-as approximate floating-point values in SQL dialect 1, but as 64-bit -integers in SQL dialect 3.

Это всего лишь предупреждающее сообщение о том, что NUMERIC и DECIMAL с точностью выше 10, и хранимые как DOUBLE PRECISION, остаются таковыми и при переходе на диалект 3. Для их изменения на хранение в INT64 см. дальше "Изменение типов данных", "NUMERIC и DECIMAL".

Кроме этого мне что-то не попадалось сообщений о генераторах. Генераторы в IB 6 64-битные, поэтому при получении их значений желательно использовать переменные или столбцы типа INT64. Если генератор используется в диалекте 1, то значение генератора "обрезается" до младших 32 бит независимо от значения генератора.
 

Другие особенности

  • IN допускает количество явно указываемы элементов (in (1, 2, 3...)) не более 1500 (на подзапросы для in это не распространяется). Если вам нужно больше, создайте таблицу, поместите туда все значения, и сделайте JOIN (явный или неявный) с этой таблицей.
  • Арифметические операции над строковыми константами больше не допускаются. Например, выполнение 1 + '2' приведет к сообщению об ошибке. В таких случаях используйте функцию CAST для явного преобразования строки в числовой тип.
 

Переходим на диалект 3

Все починили? Исправили все ошибки в скрипте? Тогда переводим базу данных диалекта 1 в диалект 3:
gfix -sql_dialect 3 database.gdb -user SYSDBA -pass masterkey

Все. После этого можно в базе данных использовать все новые возможности IB 6. Как это сделать – читайте дальше.
 

Изменение типов данных


TIMESTAMP, DATE и TIME

Как уже было написано выше, при переносе баз данных в диалект 3 старый тип DATE автоматически заменяется на TIMESTAMP. Если этот тип раньше использовался только для хранения даты (время было 0:00:00), то с этим могут быть проблемы. Например, функция CAST теперь не может быть использована для "отрезания" временной части от даты-времени. При переводе TIMESTAMP в строку функция CAST требует чтобы строка была не короче 24 символов, в противном случае будет выдаваться сообщение об ошибке. Поэтому имеет смысл сменить TIMESTAMP на DATE там, где нет нужды в хранении времени. Для этого нужно произвести следующие шаги:
  1. добавить новое поле – ALTER TABLE x ADD newdate DATE;
  2. перенести данные в новое поле – UPDATE x SET newdate =CAST (old_field AS newdate);
  3. удалить старое поле – ALTER TABLE x DROP old_field;
  4. переименовать новое поле – ALTER TABLE x ALTER COLUMN newdate TO old_field
  5. если позиция нового поля не устраивает, то следует его переместить на новое место командой ALTER TABLE x ALTER COLUMN newdate POSITION n; где n – номер старого поля old_field по порядку начиная с 1.
Замечу, что операции 1, 3, 4 и 5 не меняют структуру существующих записей, и поэтому выполняются практически мгновенно на таблицах даже с миллионами записей. Скорость выполнения операции 2, разумеется, впрямую зависит от количества записей, поэтому если у вас есть для одной таблицы несколько подобных изменений (включая и numeric-типы, о которых смотрите дальше), то стоит их сгруппировать в один UPDATE, чтобы не мучить таблицу (и себя) при переносе данных для нескольких столбцов.
 
Примечание. Тип TIME с моей точки зрения может редко пригодиться. Обычно, если хранится время, то есть вероятность его суммирования, например, учет времени телефонных разговоров – и для приложений более полезным будет хранение времени в секундах (или минутах) в типе INTEGER (но не SMALLINT, поскольку число секунд в сутках равно 86400).


NUMERIC и DECIMAL

Если в вашей базе данных были поля типов NUMERIC и DECIMAL с количеством цифр более 9 и масштабом более 2, то такие типы хранились как DOUBLE PRECISION. Это вызывало проблемы с округлением при умножении и делении, т.к. вещественные числа не могут поддерживать точность выше определенной. В IB 6 появился тип INT64, который позволяет хранить достаточно большие числа и обрабатывать их без потери точности. Но при импорте в диалект 1, и при переходе на диалект 3 поля NUMERIC и DECIMAL, хранимые как DOUBLE PRECISION, таковыми и останутся. Поэтому может иметь смысл перевести эти типы в новый формат. При создании столбца NUMERIC и DECIMAL в диалекте 3 все остается как прежде (в IB 5.x), если количество цифр числа 9 или меньше, а масштаб 2 или меньше. Если больше (например NUMERIC(15,2), то создаваемый столбец хранится как INT64. Таким образом, действуем как и в случае перехода от TIMESTAMP к DATE:
  1. добавляем новое поле – ALTER TABLE x ADD newnumeric NUMERIC(15,2);
  2. переносим данные – update x set newnumeric = old_numeric;
  3. удаляем старое поле – ALTER TABLE x DROP old_numeric;
  4. переименовываем старое поле ALTER TABLE x ALTER COLUMN newnumeric TO old_numeric
  5. если позиция нового поля не устраивает, то следует его переместить на новое место командой ALTER TABLE x ALTER COLUMN old_numeric POSITION n; где n – номер старого поля old_numeric по порядку начиная с 1.

Должен отметить, что новый стиль хранения больших чисел существенно отличается от старого. Имеется в виду сложение, умножение, вычитание и деление чисел, которые хранятся как INT64. Все это производится в соответствии со стандартом, и например при перемножении таких чисел результат будет иметь количество знаков после запятой равное сумме количества знаков после запятой у множителей.

5.33 * 5.33 = 2840.8900

В некоторых случаях это может вызвать переполнение. Очень подробно все эти особенности описаны в документе. Но даже если вам такое поведение не понравится, и вы решите оставить NUMERIC и DECIMAL без изменений, т.е. хранимые как DOUBLE PRECISION, то новые столбцы такого типа будут созданы как int64. Таким образом, вместо NUMERIC придется использовать явное объявление столбца как DOUBLE PRECISION. В общем, нужно тщательно взвесить все за и против, а заодно и проверить на тестовой базе данных.
 
Примечание. int64 – внутренний тип для хранения больших чисел, и не является ключевым словом. Для создания поля, хранящего большие целые числа, нужно пользоваться объявлением NUMERIC(15, 0) или NUMERIC(18, 0). Именовать домен как int64 не советую, т. к. в дальнейшем это слово может оказаться ключевым.

Кроме всего прочего с числами, хранящимися как int64, были некоторые проблемы при работе из Delphi 7/CBuider 6. Т. е. эти числа не совсем корректно обрабатывались на клиенте. Такие проблемы были исправлены в последних версиях IBX.


Процедуры и триггеры

Как вы уже видели, работа с числами отличается в диалектах 1 и 3. И при смене диалекта 1 на 3, если вы не делали процедурам и триггерам ALTER, они будут работать как в диалекте 1. Причиной является то, что процедуры при их создании или изменении компилируются в промежуточный формат BLR. А при переходе с одного диалекта на другой BLR не перекомпилируется. Разумеется, если вы создаете базу данных диалекта 3 из скрипта, то вычисления в процедурах и триггерах будут работать по новому. Но если вы переносите существующую базу данных, то имеет смысл тщательно просмотреть скрипт на процедуры и триггеры с вычислениями, и сделать им ALTER из клиента диалекта 3 (например IBConsole или ib_wisql. не забудьте при подсоединении установить диалект 3).

Более того, ни в коем случае нельзя допускать модификацию таких процедур и триггеров из клиентов диалекта 1. Т.е. если вы перевели базу данных в диалект 3, проверьте – не меняют ли метаданные ваши клиентские приложения, не осталось ли клиентских библиотек 5.x на компьютерах, и не осталось ли у разработчиков инструментальных средств, не позволяющих работать с диалектом 3.

Как видите, и здесь приходится сжигать мосты при переходе на диалект 3.
 

Заключение

Конечно, этот документ намного меньше, чем главы по переходу на 6.0 в документации (глава Migration Guide в Getting Started). Здесь совершенно не были затронуты особенности поведения старых (4.x и 5.x) клиентов при подсоединении к базам данных диалекта 3, а также особенности поведения клиентов 6.0 при подсоединении к серверам 4.x и 5.x и при работе с диалектами 1 и 3. Поэтому все равно вам придется прочитать Migration Guide.

Удачного вам перехода!

Подпишитесь на новости Firebird в России

Подписаться