Как конвертировать MySQL BIGINT в unsigned без потери данных? - PullRequest
0 голосов
/ 23 февраля 2020

Мне нужно преобразовать MySQL столбец таблиц базы данных из (подписанного) BIGINT в беззнаковое BIGINT. Если я это сделаю:

ALTER TABLE `$tblNm` MODIFY `flgs` BIGINT UNSIGNED;

Любые значения, для которых установлен 63-разрядный код, сбрасываются в 0!

Что мне нужно сделать, чтобы все значения были преобразованы без потерь?

Ответы [ 2 ]

1 голос
/ 23 февраля 2020

Аналогично this

Вы также можете попробовать добавить новый столбец с unsigned BIGINT

         ALTER TABLE `$tblNm`
         ADD COLUMN new_column BIGINT UNSIGNED AFTER flgs;

Затем обновите приведенные значения в новом с помощью cast

        UPDATE `$tblNm` 
        SET new_column=CAST(flgs AS UNSIGNED);

Затем удалите столбец flgs

       ALTER TABLE `$tblNm`
       DROP COLUMN flgs;

Переименуйте новый столбец с помощью flgs

       ALTER TABLE `$tblNm`
       CHANGE COLUMN new_column flgs BIGINT UNSIGNED

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

         SET autocommit=0;
         START TRANSACTION;
         ALTER TABLE `$tblNm`
         ADD COLUMN new_column BIGINT UNSIGNED AFTER flgs;
         UPDATE `$tblNm` 
         SET new_column=CAST(flgs AS UNSIGNED);
         ALTER TABLE `$tblNm`
         DROP COLUMN flgs;
         ALTER TABLE `$tblNm`
         CHANGE COLUMN new_column flgs BIGINT UNSIGNED;
         COMMIT;

EDIT-2 Если есть необходимо заблокировать таблицы перед началом транзакции, приведенный выше скрипт будет изменен на

         SET autocommit=0;
         LOCK TABLES `$tblNm` WRITE
         ALTER TABLE `$tblNm`
         ADD COLUMN new_column BIGINT UNSIGNED AFTER flgs;
         UPDATE `$tblNm` 
         SET new_column=CAST(flgs AS UNSIGNED);
         ALTER TABLE `$tblNm`
         DROP COLUMN flgs;
         ALTER TABLE `$tblNm`
         CHANGE COLUMN new_column flgs BIGINT UNSIGNED;
         COMMIT;
         UNLOCK TABLES;

В этом случае вам не нужно явно писать START TRANSACTION

0 голосов
/ 23 февраля 2020

Как я понимаю - битовая маска хранится как BIGINT (со знаком), а столбец содержит отрицательные числа (крайний левый бит установлен в 1). Вы хотите преобразовать тип столбца в BIGINT UNSIGNED, сохранив двоичное значение.

Я бы предложил преобразовать тип в BINARY(8), а затем в BIGINT UNSIGNED. К сожалению, второй шаг не сработал. Но преобразование в BIT(64) работает в моем тесте. Таким образом, вы можете попробовать:

ALTER TABLE tbl MODIFY `flgs` BIT(64);
ALTER TABLE tbl MODIFY `flgs` BIGINT UNSIGNED;

Контрольный пример:

create table tbl (flgs bigint);
insert into tbl (flgs) values (1), (-1);

ALTER TABLE tbl MODIFY `flgs` BIT(64);
ALTER TABLE tbl MODIFY `flgs` BIGINT UNSIGNED;

select * from tbl;

Возвращает:

| flgs                 |
| -------------------- |
| 1                    |
| 18446744073709551615 |

Просмотр на БД Fiddle

...