{"record":{"id":"2e5a2c57ad88e5ee","repo":"MyCATApache/Mycat-Server","slug":"sharding-column-can-t-be-updated-tablename-2e5a2c","errorCode":null,"errorMessage":"\"Sharding column can't be updated \" + tableName + \"->\" + partitionColumn","messagePattern":"\"Sharding column can't be updated \" \\+ tableName \\+ \"->\" \\+ partitionColumn","errorType":"exception","errorClass":"SQLNonTransientException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/parser/druid/impl/DruidUpdateParser.java","lineNumber":234,"sourceCode":"    private void confirmShardColumnNotUpdated(SQLUpdateStatement update,SchemaConfig schema,String tableName,String partitionColumn,String joinKey,RouteResultset rrs) throws SQLNonTransientException {\n        List<SQLUpdateSetItem> updateSetItem = update.getItems();\n        if (updateSetItem != null && updateSetItem.size() > 0) {\n            boolean hasParent = (schema.getTables().get(tableName).getParentTC() != null);\n            for (SQLUpdateSetItem item : updateSetItem) {\n                String column = StringUtil.removeBackquote(item.getColumn().toString().toUpperCase());\n                //考虑别名，前面已经限制了update分片表的个数只能有一个，所以这里别名只能是分片表的\n                if (column.contains(StringUtil.TABLE_COLUMN_SEPARATOR)) {\n                    column = column.substring(column.indexOf(\".\") + 1).trim().toUpperCase();\n                }\n                if (partitionColumn != null && partitionColumn.equals(column)) {\n                    boolean canUpdate;\n                    canUpdate = ((update.getWhere() != null) && shardColCanBeUpdated(update.getWhere(),\n                            partitionColumn, item.getValue(), false));\n\n                    if (!canUpdate) {\n                        String msg = \"Sharding column can't be updated \" + tableName + \"->\" + partitionColumn;\n                        LOGGER.warn(msg);\n                        throw new SQLNonTransientException(msg);\n                    }\n                }\n                if (hasParent) {\n                    if (column.equals(joinKey)) {\n                        String msg = \"Parent relevant column can't be updated \" + tableName + \"->\" + joinKey;\n                        LOGGER.warn(msg);\n                        throw new SQLNonTransientException(msg);\n                    }\n                    rrs.setCacheAble(true);\n                }\n            }\n        }\n    }\n}\n","sourceCodeStart":216,"sourceCodeEnd":249,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/parser/druid/impl/DruidUpdateParser.java#L216-L249","documentation":"Mycat forbids updating a table's sharding (partition) column: changing the shard key value could require moving the row to a different data node, which Mycat's UPDATE routing does not perform. In confirmShardColumnNotUpdated, if the SET item targets the partition column and shardColCanBeUpdated cannot prove the value stays routable, it throws SQLNonTransientException.","triggerScenarios":"An UPDATE SET clause assigning to the column configured as <partitionColumn> for that table (e.g. `UPDATE orders SET customer_id=456 WHERE ...`) when the new value is not provably in the same shard.","commonSituations":"Data-correction scripts changing the shard key; ETL jobs backfilling the partition column; apps reassigning ownership of a row (e.g. moving an order to another customer).","solutions":["Remove the sharding column from the SET list; update it via DELETE + INSERT into the correct shard instead","If the new value maps to the same data node, keep it but be aware shardColCanBeUpdated must be able to prove routability from the literal","Redesign the schema so frequently-updated fields are not used as the partition column"],"exampleFix":"-- before\nUPDATE orders SET customer_id = 456 WHERE order_id = 1001;\n-- after\nINSERT INTO orders (order_id, customer_id, ...) SELECT ... -- insert into target shard with new key\nDELETE FROM orders WHERE order_id = 1001; -- remove from old shard","handlingStrategy":"validation","validationCode":"if (updateSetColumns.contains(tableConfig.getPartitionColumn())) {\n    throw new IllegalArgumentException(\"cannot update sharding column \" + tableConfig.getPartitionColumn());\n}","typeGuard":null,"tryCatchPattern":"try { executeUpdate(sql); } catch (SQLNonTransientException e) { if (e.getMessage().startsWith(\"Sharding column can't be updated\")) { doDeleteInsertInstead(); } else throw e; }","preventionTips":["Treat the partition column as immutable after insert","Use delete+insert flows to change shard keys","Choose stable, rarely-modified columns as partition columns","Block shard-key columns in ORM dirty-checking/update builders"],"tags":["mysql","sharding","update","partition-column"],"backgroundTag":"unsupported-operation","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}