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

Начиная с версии 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"


    (c) iBase, www.ibase.ru