From 8beb6fccb640759c24e7adf0d9ef055e69d0b25f Mon Sep 17 00:00:00 2001 From: ekexium Date: Wed, 4 Feb 2026 11:29:51 +0800 Subject: [PATCH 1/4] nontransactional dml FAQ about alias Signed-off-by: ekexium --- non-transactional-dml.md | 19 +++++++++++++++++++ sql-statements/sql-statement-batch.md | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/non-transactional-dml.md b/non-transactional-dml.md index afee2fece7e0..1dbfd52e9f04 100644 --- a/non-transactional-dml.md +++ b/non-transactional-dml.md @@ -365,6 +365,25 @@ SELECT t2.id, t2.v, t3.id FROM t2 JOIN t3 ON t2.id = t3.id +----------------+---------------+ ``` +### 执行带表别名的非事务 DML 语句后,遇到 `Unknown column '别名.列' in 'where clause'` 错误 + +非事务 DML 语句在内部会构造用于划分 batch 的查询语句(可通过 [`DRY RUN QUERY`](/non-transactional-dml.md#查询非事务-dml-语句中划分-batch-的语句) 查看),并生成拆分后的实际执行语句(可通过 [`DRY RUN`](/non-transactional-dml.md#查询非事务-dml-语句中首末-batch-对应的语句) 查看)。在当前实现中,这些重写后的语句可能不会保留原始 DML 语句中的表别名(alias)。如果 `WHERE` 子句或其它表达式中使用了 `别名.列` 的形式,就可能出现 `Unknown column` 报错。 + +例如,下面的语句在某些情况下会报错: + +```sql +BATCH ON t_old.id LIMIT 5000 +INSERT INTO t_new +SELECT * FROM t_old AS t +WHERE t.c1 IS NULL; +``` + +要避免该错误,建议: + +- 尽量不要在非事务 DML 语句中使用表别名,将 `t.c1` 改写为 `c1` 或 `t_old.c1`。 +- 指定[划分列](#参数说明)时,不要使用表别名。例如,不要写 `BATCH ON t.id`,应写 `BATCH ON db.t_old.id` 或 `BATCH ON t_old.id`。 +- 先使用 `DRY RUN QUERY`/`DRY RUN` 预览拆分后的语句,确认重写后的语句与预期一致。 + ### 实际的 batch 大小和指定的 batch size 不一样 在非事务 DML 语句的执行过程中,最后一个 batch 处理的数据量可能会小于 batch size。 diff --git a/sql-statements/sql-statement-batch.md b/sql-statements/sql-statement-batch.md index 704834bd7641..4c8083fbfa57 100644 --- a/sql-statements/sql-statement-batch.md +++ b/sql-statements/sql-statement-batch.md @@ -27,6 +27,10 @@ BATCH ON id LIMIT 1 INSERT INTO t SELECT t2.id, t2.v, t3.v FROM t2 JOIN t3 ON t2 Non-transactional DML, shard column must be fully specified ``` +> **注意:** +> +> `BATCH` 语句在内部会重写并拆分执行 DML。当前实现中表别名(alias)可能不会被保留,导致 `Unknown column ... in 'where clause'` 等报错。建议避免使用表别名,并先使用 `DRY RUN QUERY`/`DRY RUN` 预览拆分后的语句。详见[非事务 DML 语句](/non-transactional-dml.md)。 + ## 语法图 ```ebnf+diagram From 06b332783e0fa5a6a73c086973bfe3f332f3bde5 Mon Sep 17 00:00:00 2001 From: Ziqian Qin Date: Wed, 4 Mar 2026 11:08:06 +0800 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Aolin --- non-transactional-dml.md | 14 ++++++++------ sql-statements/sql-statement-batch.md | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/non-transactional-dml.md b/non-transactional-dml.md index 1dbfd52e9f04..5c328136d8af 100644 --- a/non-transactional-dml.md +++ b/non-transactional-dml.md @@ -365,9 +365,11 @@ SELECT t2.id, t2.v, t3.id FROM t2 JOIN t3 ON t2.id = t3.id +----------------+---------------+ ``` -### 执行带表别名的非事务 DML 语句后,遇到 `Unknown column '别名.列' in 'where clause'` 错误 +### 执行带表别名的非事务 DML 语句后,遇到 `Unknown column '.' in 'where clause'` 错误 -非事务 DML 语句在内部会构造用于划分 batch 的查询语句(可通过 [`DRY RUN QUERY`](/non-transactional-dml.md#查询非事务-dml-语句中划分-batch-的语句) 查看),并生成拆分后的实际执行语句(可通过 [`DRY RUN`](/non-transactional-dml.md#查询非事务-dml-语句中首末-batch-对应的语句) 查看)。在当前实现中,这些重写后的语句可能不会保留原始 DML 语句中的表别名(alias)。如果 `WHERE` 子句或其它表达式中使用了 `别名.列` 的形式,就可能出现 `Unknown column` 报错。 +非事务 DML 语句在执行时,TiDB 会在内部构造用于划分 batch 的查询语句,并生成拆分后的实际执行语句。你可以分别通过 [`DRY RUN QUERY`](/non-transactional-dml.md#查询非事务-dml-语句中划分-batch-的语句) 和 [`DRY RUN`](/non-transactional-dml.md#查询非事务-dml-语句中首末-batch-对应的语句) 查看这两类语句。 + +在当前版本中,这些重写后的语句可能不会保留原始 DML 语句中的表别名 (alias)。因此,如果 `WHERE` 子句或其他表达式中使用了 `.` 的形式引用列,就可能出现 `Unknown column` 报错。 例如,下面的语句在某些情况下会报错: @@ -378,11 +380,11 @@ SELECT * FROM t_old AS t WHERE t.c1 IS NULL; ``` -要避免该错误,建议: +要避免该错误,建议采取以下措施: -- 尽量不要在非事务 DML 语句中使用表别名,将 `t.c1` 改写为 `c1` 或 `t_old.c1`。 -- 指定[划分列](#参数说明)时,不要使用表别名。例如,不要写 `BATCH ON t.id`,应写 `BATCH ON db.t_old.id` 或 `BATCH ON t_old.id`。 -- 先使用 `DRY RUN QUERY`/`DRY RUN` 预览拆分后的语句,确认重写后的语句与预期一致。 +- 尽量不要在非事务 DML 语句中使用表别名。例如,将 `t.c1` 改写为 `c1` 或 `t_old.c1`。 +- 在指定[划分列](#参数说明)时,不要使用表别名。例如,将 `BATCH ON t.id` 改写为 `BATCH ON db.t_old.id` 或 `BATCH ON t_old.id`。 +- 在执行前使用 `DRY RUN QUERY` 或 `DRY RUN` 预览拆分后的语句,确保重写后的语句符合预期。 ### 实际的 batch 大小和指定的 batch size 不一样 diff --git a/sql-statements/sql-statement-batch.md b/sql-statements/sql-statement-batch.md index 4c8083fbfa57..9c049764d991 100644 --- a/sql-statements/sql-statement-batch.md +++ b/sql-statements/sql-statement-batch.md @@ -29,7 +29,7 @@ Non-transactional DML, shard column must be fully specified > **注意:** > -> `BATCH` 语句在内部会重写并拆分执行 DML。当前实现中表别名(alias)可能不会被保留,导致 `Unknown column ... in 'where clause'` 等报错。建议避免使用表别名,并先使用 `DRY RUN QUERY`/`DRY RUN` 预览拆分后的语句。详见[非事务 DML 语句](/non-transactional-dml.md)。 +> `BATCH` 语句在执行时会被内部重写并拆分为多个 DML 语句。在当前版本中,表别名(alias) 可能不会被保留,从而导致 `Unknown column ... in 'where clause'` 等报错。建议避免使用表别名,并在执行前使用 `DRY RUN QUERY` 或 `DRY RUN` 预览拆分后的语句。详见[非事务 DML 语句](/non-transactional-dml.md)。 ## 语法图 From afa30857e06907c4994613386b99a7dd95d26f88 Mon Sep 17 00:00:00 2001 From: Aolin Date: Wed, 4 Mar 2026 15:33:01 +0800 Subject: [PATCH 3/4] Apply suggestions from code review --- sql-statements/sql-statement-batch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql-statements/sql-statement-batch.md b/sql-statements/sql-statement-batch.md index 9c049764d991..a6dfe1fc26f0 100644 --- a/sql-statements/sql-statement-batch.md +++ b/sql-statements/sql-statement-batch.md @@ -29,7 +29,7 @@ Non-transactional DML, shard column must be fully specified > **注意:** > -> `BATCH` 语句在执行时会被内部重写并拆分为多个 DML 语句。在当前版本中,表别名(alias) 可能不会被保留,从而导致 `Unknown column ... in 'where clause'` 等报错。建议避免使用表别名,并在执行前使用 `DRY RUN QUERY` 或 `DRY RUN` 预览拆分后的语句。详见[非事务 DML 语句](/non-transactional-dml.md)。 +> `BATCH` 语句在执行时会被内部重写并拆分为多个 DML 语句。在当前版本中,表别名 (alias) 可能不会被保留,从而导致 `Unknown column ... in 'where clause'` 等报错。建议避免使用表别名,并在执行前使用 `DRY RUN QUERY` 或 `DRY RUN` 预览拆分后的语句。详见[非事务 DML 语句](/non-transactional-dml.md)。 ## 语法图 From b7b810afacf1e2d409a6cdda2769bdf7a0312fd7 Mon Sep 17 00:00:00 2001 From: Aolin Date: Wed, 4 Mar 2026 16:02:54 +0800 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: xixirangrang --- sql-statements/sql-statement-batch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql-statements/sql-statement-batch.md b/sql-statements/sql-statement-batch.md index a6dfe1fc26f0..6e561428078c 100644 --- a/sql-statements/sql-statement-batch.md +++ b/sql-statements/sql-statement-batch.md @@ -29,7 +29,7 @@ Non-transactional DML, shard column must be fully specified > **注意:** > -> `BATCH` 语句在执行时会被内部重写并拆分为多个 DML 语句。在当前版本中,表别名 (alias) 可能不会被保留,从而导致 `Unknown column ... in 'where clause'` 等报错。建议避免使用表别名,并在执行前使用 `DRY RUN QUERY` 或 `DRY RUN` 预览拆分后的语句。详见[非事务 DML 语句](/non-transactional-dml.md)。 +> `BATCH` 语句在执行时会被内部重写并拆分为多个 DML 语句。在当前版本中,表别名 (alias) 可能不会被保留,从而导致 `Unknown column '.' in 'where clause'` 等报错。建议避免使用表别名,并在执行前使用 `DRY RUN QUERY` 或 `DRY RUN` 预览拆分后的语句。详见[非事务 DML 语句](/non-transactional-dml.md)。 ## 语法图