Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在不丢失数据的情况下将MySQL的BIGINT转换为unsigned?_Mysql_Type Conversion_Bigint - Fatal编程技术网

如何在不丢失数据的情况下将MySQL的BIGINT转换为unsigned?

如何在不丢失数据的情况下将MySQL的BIGINT转换为unsigned?,mysql,type-conversion,bigint,Mysql,Type Conversion,Bigint,我需要将MySQL数据库表列从有符号的BIGINT转换为无符号的BIGINT。如果我这样做: ALTER TABLE `$tblNm` MODIFY `flgs` BIGINT UNSIGNED; 设置了63位的任何值都将重置为0 我需要做什么才能转换所有值而不丢失?类似于 您还可以尝试添加带有无符号BIGINT的新列 然后使用cast更新新列中的casted值 然后放下flgs柱 使用flgs重命名新列 编辑 为了在事务中执行此操作,我们可以如下更新此操作 SET auto

我需要将MySQL数据库表列从有符号的BIGINT转换为无符号的BIGINT。如果我这样做:

ALTER TABLE `$tblNm` MODIFY `flgs` BIGINT UNSIGNED;
设置了63位的任何值都将重置为0

我需要做什么才能转换所有值而不丢失?

类似于

您还可以尝试添加带有无符号BIGINT的新列

然后使用cast更新新列中的casted值

然后放下flgs柱

使用flgs重命名新列

编辑 为了在事务中执行此操作,我们可以如下更新此操作

         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;
编辑-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;

在这种情况下,您不需要显式地写入启动事务,正如我所理解的那样-您有一个位掩码存储为BIGINT signed,列包含负数,最左边的位设置为1。您希望将列类型转换为保留二进制值的BIGINT UNSIGNED

我建议将类型转换为BINARY8,然后再转换为biginunsigned。不幸的是,第二步没有成功。但是在我的测试中转换位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 |

您的INSERT INTO语句有一个错误,它可能是一个更新,但除此之外,我喜欢这个想法。这就像是一个大的杀伤力,但似乎没有其他方法不丢失数据。演员必须是未签名的CASTflgs,而不是你在那里拥有的。然后必须有DROP列,后跟CHANGE列。因此,为什么不调整所有这些,我将把它标记为一个答案——除非其他人有更好的想法?我没有指定MySQL的版本,所以可能您的语法适用于较新的版本。我在5.7.25上,那里的CASTflgs必须是UNSIGNED,并且重命名ALTER TABLE tbl CHANGE new_column flgs BIGINT UNSIGNED。这可能需要一个事务或MySQL中的任何调用。设置自动提交=0;然后将其包装在BEGIN和COMMITID中,我们需要锁定表还是在BEGIN之后自动锁定表?此资料-从tbl LIMIT 018446744073709551615中选择*进行更新;嘿,有人不喜欢这个问题:是的,谢谢。这可能是一个更好的解决方案。此时,我已经使用我标记的方法转换了所有数据。因此,如果其他人遇到同样的问题,他们可能会尝试你的方法。
         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;
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 |