MySQL生成列修改默认值时触发[42000][1064]语法错误求助
问题
我尝试为生成列设置包含指定表达式的默认值,该表达式在SELECT查询中可正常运行:
select from_unixtime(CONCAT(LEFT(jdoc->'$.ts', LENGTH(jdoc->'$.ts') - CHAR_LENGTH(jdoc->'$.sts')), jdoc->'$.sts')) as calc_ts from table_name
但执行ALTER TABLE语句修改列默认值时却无法正常工作:
alter table table_name alter column sts_date set default from_unixtime( CONCAT(LEFT(jdoc -> '$.ts', LENGTH(jdoc -> '$.ts') - CHAR_LENGTH(jdoc -> '$.sts')), jdoc -> '$.sts') / 1000);
返回错误:
[42000][1064] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from_unixtime( CONCAT(LEFT(jdoc -> '$.ts', LENGTH(jdoc -> '$.ts'' at line 2.
原因与解决办法
- MySQL默认值的列依赖限制:MySQL不允许列默认值引用表内其他字段的值,哪怕该表达式在SELECT查询中能正常运行。默认值必须是常量、不依赖表内列的确定性函数,或是符合特定规则的简单表达式,无法直接依赖
jdoc这类其他列做计算。 - JSON路径的解析限制:在默认值表达式的上下文里,MySQL的语法解析器对
jdoc -> '$.ts'这类JSON路径引用的支持有限,直接使用会触发语法解析错误,也就是你遇到的1064报错。 - 可行替代方案:
- 若
sts_date是生成列,直接定义生成规则而非默认值:ALTER TABLE table_name MODIFY COLUMN sts_date DATETIME GENERATED ALWAYS AS ( from_unixtime( CONCAT(LEFT(jdoc->'$.ts', LENGTH(jdoc->'$.ts') - CHAR_LENGTH(jdoc->'$.sts')), jdoc->'$.sts') / 1000 ) ) STORED; - 若必须用默认值(非生成列场景),可以通过触发器实现:在插入或更新行时,自动计算并赋值给
sts_date,触发器允许自由引用表内其他列的值。
- 若
内容的提问来源于stack exchange,提问作者NeverBe
相关产品推荐
相关产品推荐

