Как изменить тип поля, длину поля или порядок полей?
Начиная с версии InterBase 6.0 все нижеизложенное является хаком, т. к. в InterBase 6 и всех версиях выше (InterBase, Firebird, Yaffil) поддерживается оператор alter table alter column. См. документацию.
Начнем с того, что в стандарте (ANSI SQL 92 entry level) нет определени языковых конструкций для модификации типа поля. Однако ядро IB вполне может выполнять такие действия благодаря специальному механизму отслеживани соответствия физических данных, и информации об их типах в системных таблицах.
- Найдите ваше поле в таблице RDB$RELATION_FIELDS по названию пол (RBD$.FIELD_NAME) и имени таблицы (RDB$RELATION_NAME). Запомните содержимое поля RDB$FIELD_SOURCE – там должно быть нечто вроде RDB$nnn.
- Найденное RDB$nnn теперь найдите в таблице RDB$FIELDS
- Поменяйте на нужные значения длину поля (RDB$FIELD_LENGTH) или тип поля (RDB$FIELD_TYPE). Порядок полей меняется в поле RDB$FIELD_POSITION
Примечание. В Database Explorer можно ускорить выполнение пункта 1 – откройте вашу БД, выберите Tables, нужную таблицу, Columns, и нужное поле. в Field Definition значению поля Domain и соответствует то, что вы ищете (RDB$nnn). Далее выполняйте пункты 2 и 3.
- Старые данные, если вы изменили тип поля, будут конвертироваться в новый формат
- Новые данные будут записываться в новом формате.
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»
Copyright iBase.ru © 2002-2023
Как изменить тип данных столбца если таблица заполнена и используется?
Есть столбец ID с числовыми значениями. При создании таблицы, в следствии ошибки проектирования, он был объявлен как VARCHAR . С этим столбцом постоянно возникают проблемы, например, сравнение значений столбца может привести к неожидаемым результатам:
select to_number (max (id)) maxid from ( select '9' id from dual union all select '10' from dual); MAXID ---------- 9
Есть решение — изменить тип данных столбца:
alter table table1 modify id number(10,0);
, но оно выдает ошибку:
ORA-01439: column to be modified must be empty to change datatype
Какой наилучший метод решения этой проблемы?
Отслеживать
задан 22 авг 2021 в 20:32
51.6k 200 200 золотых знаков 61 61 серебряный знак 242 242 бронзовых знака
ассоциация:stackoverflow.com/q/64352726
22 авг 2021 в 21:24
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Можно реорганизовать таблицу во время её использования с помощью PL/SQL пакета DBMS_REDEFINITION.
create table t1 ( id varchar2 (10) primary key); create table t2 ( id number(10,0) primary key); insert into t1 select '9' from dual union all select '10' from dual; commit; begin dbms_redefinition.start_redef_table ( uname=>user, orig_table=>'t1', int_table=>'t2', col_mapping => 'to_number (id) id', options_flag => dbms_redefinition.cons_use_rowid); end; / exec dbms_redefinition.sync_interim_table (user, 't1', 't2');
При завершении реорганизации, таблица t1 будет кратковременно заблокирована, а затем она полностью соответствует по структуре таблице t2 , и последняя может быть удалена:
exec dbms_redefinition.finish_redef_table (user, 't1', 't2'); desc t1 Name Null? Type ---- -------- ---------- ID NOT NULL NUMBER(10) select max (id) maxid from t1; MAXID ---------- 10 drop table t2 cascade constraints purge;
Безопасное изменение типа поля в PostgreSQL
На первый взгляд может показаться, что в PostgreSQL изменить тип поля можно очень просто, используя команду ALTER. Но это не всегда возможно. В качестве примера рассмотрим таблицу, в которой хранится список покупателей.
Представьте, что в нашей таблице есть поле customer_id , где применяется строковый тип данных varchar. Налицо ошибка, ведь в этом поле предполагается хранить идентификаторы покупателей, имеющие целочисленный формат integer. Давайте попробуем исправить ошибку, используя ALTER:
ALTER TABLE customers ALTER COLUMN customer_id TYPE integer;Как некоторые уже догадались, ничего не выйдет:
ERROR: column “customer_id” cannot be cast automatically to type integer SQL state: 42804 Hint: Specify a USING expression to perform the conversion.А всё потому, что нельзя так просто взять и поменять тип поля, если в таблице содержатся данные. Так как применялся тип varchar, у PostgreSQL не получается определить принадлежность значения к integer.
Вопрос можно решить, используя USING — выражение, указанное в сообщении об ошибке. Так мы выполним преобразование данных в integer корректно:
ALTER TABLE customers ALTER COLUMN customer_id TYPE integer USING (customer_id::integer);В итоге всё пройдёт без сложностей:
Что-нибудь ещё?
Используя USING, мы можем кроме конкретного выражения применять функции, операторы, другие поля. К примеру, давайте выполним преобразование поля customer_id обратно в varchar, но уже преобразовав формат данных:
ALTER TABLE customers ALTER COLUMN customer_id TYPE varchar USING (customer_id || '-' || first_name);В конечном итоге наша таблица будет выглядеть так:
postgresql как изменить тип поля с integer на serial?
Кроме создания заново таблицы ничего не приходит на ум.
cetjs2 ★★★★★
01.11.17 00:04:20 MSK
pi11 ★★★★★
( 01.11.17 00:13:34 MSK )
Ответ на: комментарий от pi11 01.11.17 00:13:34 MSKЯ к тому, что - создаешь секвинс, потом alter column set default nexval('твой_секвинс');
вот тебе и поле сериал стало.
pi11 ★★★★★
( 01.11.17 00:20:04 MSK )
Ответ на: комментарий от pi11 01.11.17 00:20:04 MSK
cetjs2 ★★★★★
( 01.11.17 00:23:27 MSK ) автор топика
Ответ на: комментарий от pi11 01.11.17 00:20:04 MSK
Ещё не забыть сделать столбец таблицы владельцем последовательности.
theNamelessOne ★★★★★
( 01.11.17 00:49:47 MSK )В postgresql 10 уже стоит использовать тип identity/bigidentity - это улучшенный serial/bigserial.
dmitry_vk ★★★
( 01.11.17 12:26:45 MSK )
Ответ на: комментарий от dmitry_vk 01.11.17 12:26:45 MSKв убунте 17.10 до сих пор 9.6, увы. ждем в 18.04.
cetjs2 ★★★★★
( 01.11.17 15:19:04 MSK ) автор топика
Ответ на: комментарий от cetjs2 01.11.17 15:19:04 MSKДля постгреса _всегда_ пользуйся репозиторием от _авторов постгреса_ , а не репозиторием дистра.
anonymous
( 01.11.17 15:56:39 MSK )
Ответ на: комментарий от anonymous 01.11.17 15:56:39 MSK
cetjs2 ★★★★★
( 01.11.17 17:00:03 MSK ) автор топика
Ответ на: комментарий от anonymous 01.11.17 15:56:39 MSK
slovazap ★★★★★
( 01.11.17 17:00:23 MSK )
Ответ на: комментарий от cetjs2 01.11.17 15:19:04 MSK
deadNightTiger ★★★★★
( 01.11.17 17:43:41 MSK )
Ответ на: комментарий от slovazap 01.11.17 17:00:23 MSKЭто ты про постгрес так ?
anonymous
( 02.11.17 00:01:30 MSK )
Ответ на: комментарий от anonymous 02.11.17 00:01:30 MSKЭто я про безграмотный совет от профнепригодного анонимуса.
slovazap ★★★★★
( 02.11.17 12:53:42 MSK )
Последнее исправление: slovazap 02.11.17 12:54:07 MSK (всего исправлений: 1)Ответ на: комментарий от slovazap 02.11.17 12:53:42 MSK
Ну пруфани проблемы с пакетами из репозитория разрабов профпригодник ты наш, говорить все горазды.
anonymous
( 02.11.17 16:21:28 MSK )
Ответ на: комментарий от slovazap 02.11.17 12:53:42 MSKэто отличный совет. если чета начнет глючить, в рассылке первым делом посоветуют поставить вместо левых пакетов из дистра, официальные, потом уже дальше будут разбираться.
этоже касается nginx и node.
drsm ★★
( 02.11.17 19:47:02 MSK )
Ответ на: комментарий от drsm 02.11.17 19:47:02 MSKПоставить пакеты от авторов могут советовать только абсолютно безграмотные люди, это совет уровня «выключить и снова включить». Такие же безграмотные люди пишут эти пакеты, поскольку мантейнерами дистрибутива они не являются и от пакетирования очень далеки, пакет не проходит никакого review и QA, и также разрабатывается отдельно от основного репозитория, поэтому обновление основного репозитория может его в любой момент сломать. Я наступал в проблемы с «официальными» пакетами от авторов много раз, и держаться от них подальше - единственный действительно хороший совет.


