Как изменить тип поля, длину поля или порядок полей?

Начиная с версии InterBase 6.0 все нижеизложенное является хаком, т. к. в InterBase 6 и всех версиях выше (InterBase, Firebird, Yaffil) поддерживается оператор alter table alter column. См. документацию.

Начнем с того, что в стандарте (ANSI SQL 92 entry level) нет определени языковых конструкций для модификации типа поля. Однако ядро IB вполне может выполнять такие действия благодаря специальному механизму отслеживани соответствия физических данных, и информации об их типах в системных таблицах.

Делается это так (лучше всего запустить Database Explorer с включенным пунктом View/System Data):
  1. Найдите ваше поле в таблице RDB$RELATION_FIELDS по названию пол (RBD$.FIELD_NAME) и имени таблицы (RDB$RELATION_NAME). Запомните содержимое поля RDB$FIELD_SOURCE – там должно быть нечто вроде RDB$nnn.
  2. Найденное RDB$nnn теперь найдите в таблице RDB$FIELDS
  3. Поменяйте на нужные значения длину поля (RDB$FIELD_LENGTH) или тип поля (RDB$FIELD_TYPE). Порядок полей меняется в поле RDB$FIELD_POSITION
Примечание. В Database Explorer можно ускорить выполнение пункта 1 – откройте вашу БД, выберите Tables, нужную таблицу, Columns, и нужное поле. в Field Definition значению поля Domain и соответствует то, что вы ищете (RDB$nnn). Далее выполняйте пункты 2 и 3.
При этом вы все еще будете продолжать видеть старую информацию о полях таблицы. Новую структуру вы увидите после пересоединения к БД. При этом в БД будет происходить следующее:
  • Старые данные, если вы изменили тип поля, будут конвертироваться в новый формат
  • Новые данные будут записываться в новом формате.

Особенно полезно такое свойство IB, когда вам нужно изменить длину строкового поля, которую вы может быть опрометчиво определили слишком маленькой. Например, CHAR(20) на CHAR(50) и т. д. Если вы боитесь, что база данных при увеличении длины строковых полей сильно вырастет – читайте соответствующий документ.

Ann Harrison предложила готовые запросы для изменения длины строковых (CHAR и VARCHAR) типов у таблиц:
update rdb$fields set rdb$field_length = 20 
where rdb$field_length = 10
        and  rdb$field_name = (select rfr.rdb$field_source
                               from rdb$relation_fields rfr
                               where rdb$relation_name = "YOUR TABLE"
                                   and rdb$field_name = "YOUR COLUMN")
и у процедур:
update rdb$fields set rdb$field_length = 20
where rdb$field_length = 10
        and rdb$field_name = (select ppr.rdb$field_source
                              from rdb$procedure_parameters ppr
                              where rdb$procedure_name = "YOUR PROCEDURE"
                                  and rdb$parameter_name = "YOUR PARAMETER")

Изменение типа BLOB: (в данном примере с любого подтипа на подтип 0)
update rdb$fields f set f.rdb$field_sub_type = 0
where f.rdb$field_name =
      (select rfr.rdb$field_source
       from rdb$relation_fields rfr
       where rfr.rdb$field_name = "COLUMN_NAME" and rfr.rdb$relation_name = "TABLE_NAME"

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

Подписаться