Skip to content

sql-statement: update sql-statement-change-column #13817

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions functions-and-operators/cast-functions-and-operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,13 @@ Cast 函数和操作符用于将某种数据类型的值转换为另一种数据
> **注意:**
>
> TiDB 和 MySQL 对于 `SELECT CAST(MeN AS CHAR)`(或者等价的 `SELECT CONVERT(MeM, CHAR)`)的结果显示不一致,其中 `MeN` 是用科学计数法表示的双精度浮点数。MySQL 在 `-15 <= N <= 14` 时显示完整数值,在 `N < -15` 或 `N > 14` 时显示科学计数法。而 TiDB 始终显示完整数值。例如,MySQL 对于 `SELECT CAST(3.1415e15 AS CHAR)` 的显示结果为 `3.1415e15`,而 TiDB 的显示结果为 `3141500000000000`。

## MySQL 兼容性

TiDB 不支持部分数据类型的变更,例如部分时间类型、Bit、Set、Enum 和 JSON 等。

```sql
CREATE TABLE t (a DECIMAL(13, 7));
ALTER TABLE t CHANGE COLUMN a a DATETIME;
ERROR 8200 (HY000): Unsupported modify column: [ddl:8200]Unsupported modify column: change from original type decimal(13,7) to datetime is currently unsupported yet
```
147 changes: 88 additions & 59 deletions sql-statements/sql-statement-change-column.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-change-column/','/docs-cn/d

# CHANGE COLUMN

`ALTER TABLE.. CHANGE COLUMN` 语句用于在已有表上更改列,包括对列进行重命名,和将数据改为兼容类型。
`ALTER TABLE .. CHANGE COLUMN` 语句用于在已有表上更改列,包括对列进行重命名,和将数据改为兼容类型。

从 v5.1.0 版本起,TiDB 开始支持 Reorg 数据的类型变更,包括但不限于:

- 从 varchar 转换为 bigint
- 从 varchar 转换为 bigint
- decimal 精度修改
- 从 varchar(10) 到 varchar(5) 的长度压缩

Expand Down Expand Up @@ -52,108 +52,137 @@ ColumnName ::=

## 示例

{{< copyable "sql" >}}
创建表 `t1` 并插入数据:

```sql
CREATE TABLE t1 (id int not null primary key AUTO_INCREMENT, col1 INT);
INSERT INTO t1 (col1) VALUES (1),(2),(3),(4),(5);
SELECT * FROM t1;
```

```
Query OK, 0 rows affected (0.11 sec)
```

{{< copyable "sql" >}}
表 `t1` 的数据如下:

```sql
INSERT INTO t1 (col1) VALUES (1),(2),(3),(4),(5);
+----+------+
| id | col1 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.01 sec)
```

```
Query OK, 5 rows affected (0.02 sec)
Records: 5 Duplicates: 0 Warnings: 0
```

{{< copyable "sql" >}}
将表 `t1` 的列 `col1` 重命名为 `col2`:

```sql
ALTER TABLE t1 CHANGE col1 col2 INT;
SELECT * FROM t1;
```

```
Query OK, 0 rows affected (0.09 sec)
```

{{< copyable "sql" >}}
表 `t1` 的数据如下:

```sql
ALTER TABLE t1 CHANGE col2 col3 BIGINT, ALGORITHM=INSTANT;
+----+------+
| id | col2 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.01 sec)
```

```
Query OK, 0 rows affected (0.08 sec)
```

{{< copyable "sql" >}}
将表 `t1` 的列 `col2` 重命名为 `col3`,并将列的类型从 `INT` 改为 `BIGINT`:

```sql
ALTER TABLE t1 CHANGE col3 col4 BIGINT, CHANGE id id2 INT NOT NULL;
```

```
ERROR 1105 (HY000): can't run multi schema change
ALTER TABLE t1 CHANGE col2 col3 BIGINT, ALGORITHM=INSTANT;
SELECT * FROM t1;
```

{{< copyable "sql" >}}
表 `t1` 的数据如下:

```sql
CREATE TABLE t (a int primary key);
ALTER TABLE t CHANGE COLUMN a a VARCHAR(10);
+----+------+
| id | col3 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.00 sec)
```

```
ERROR 8200 (HY000): Unsupported modify column: column has primary key flag
```

{{< copyable "sql" >}}
下面语句将表 `t1` 的列 `col3` 重命名为 `col4`,并将主键 `id` 重命名为 `id2`:

```sql
CREATE TABLE t (c1 INT, c2 INT, c3 INT) partition by range columns(c1) ( partition p0 values less than (10), partition p1 values less than (maxvalue));
ALTER TABLE t CHANGE COLUMN c1 c1 DATETIME;
```

```
ERROR 8200 (HY000): Unsupported modify column: table is partition table
ALTER TABLE t1 CHANGE col3 col4 BIGINT, CHANGE id id2 INT NOT NULL;
ERROR 8200 (HY000): Unsupported modify column: can't remove auto_increment without @@tidb_allow_remove_auto_inc enabled
```

{{< copyable "sql" >}}
由于 `id` 是自增列,所以不能直接将其重命名为 `id2`。需要先开启 [`tidb_allow_remove_auto_inc`](/system-variables.md#tidb_allow_remove_auto_inc-从-v2118-和-v304-版本开始引入),然后再执行 `ALTER TABLE` 语句:

```sql
CREATE TABLE t (a INT, b INT as (a+1));
ALTER TABLE t CHANGE COLUMN b b VARCHAR(10);
```

```
ERROR 8200 (HY000): Unsupported modify column: column is generated
SET tidb_allow_remove_auto_inc = ON;
ALTER TABLE t1 CHANGE col3 col4 BIGINT, CHANGE id id2 INT NOT NULL;
SELECT * FROM t1;
```

{{< copyable "sql" >}}

```sql
CREATE TABLE t (a DECIMAL(13, 7));
ALTER TABLE t CHANGE COLUMN a a DATETIME;
```
表 `t1` 的数据如下:

```
ERROR 8200 (HY000): Unsupported modify column: change from original type decimal(13,7) to datetime is currently unsupported yet
+-----+------+
| id2 | col4 |
+-----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+-----+------+
5 rows in set (0.00 sec)
```

## MySQL 兼容性

* 不支持主键列上 [Reorg-Data](/sql-statements/sql-statement-modify-column.md#reorg-data-change) 类型的变更。

```sql
CREATE TABLE t (a int primary key);
ALTER TABLE t CHANGE COLUMN a a VARCHAR(10);
ERROR 8200 (HY000): Unsupported modify column: this column has primary key flag
```

* 不支持分区表上的列类型变更。

```sql
CREATE TABLE t (c1 INT, c2 INT, c3 INT) partition by range columns(c1) ( partition p0 values less than (10), partition p1 values less than (maxvalue));
ALTER TABLE t CHANGE COLUMN c1 c1 DATETIME;
ERROR 8200 (HY000): Unsupported modify column: table is partition table
```

* 不支持生成列上的列类型变更。

```sql
CREATE TABLE t (a INT, b INT as (a+1));
ALTER TABLE t CHANGE COLUMN b b VARCHAR(10);
ERROR 8200 (HY000): Unsupported modify column: newCol IsGenerated false, oldCol IsGenerated true
```

* 不支持部分数据类型(例如,部分时间类型、Bit、Set、Enum、JSON 等)的变更,因为 TiDB 中 `CAST` 函数与 MySQL 的行为存在兼容性问题。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cast 的兼容性问题有文档描述吗?看 cast 函数的文档里没有提

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有一些问题,没有文档


```sql
CREATE TABLE t (a DECIMAL(13, 7));
ALTER TABLE t CHANGE COLUMN a a DATETIME;
ERROR 8200 (HY000): Unsupported modify column: [ddl:8200]Unsupported modify column: change from original type decimal(13,7) to datetime is currently unsupported yet
```

## 另请参阅

* [CREATE TABLE](/sql-statements/sql-statement-create-table.md)
Expand Down