---
order: 14
navTitle: alter-table.ftl
---
# alter-table.ftl

在alter-table.ftl文件中用Freemaker构造一个SQL模板，使数据库支持`alter table`语句。

```json
<#--修改表ftl模板-->
<#--修改表注释-->
<#if (originAttributes.tableComment)?? && !(attributes.tableComment)??>
ALTER TABLE ${tableName} COMMENT '';
<#elseif (alterAttributes.tableComment)??>
ALTER TABLE ${tableName} COMMENT '${alterAttributes.tableComment}';
</#if>
<#--新增字段-->
<#if newColumns??>
	<#list newColumns as col>
	<#assign isVarchar = col.dbType=="VARCHAR"||col.dbType=="CHAR"|| col.dbType=='LONGTEXT'>
		ALTER TABLE ${tableName} ADD ${col.name+" "}<#t>
		<#if col.autoInc!false>
			BIGINT NOT NULL AUTO_INCREMENT<#t>
		<#else>
			${col.typeDeclaration}<#if isVarchar> BINARY</#if><#t>
			<#if !col.nullable!true> NOT NULL</#if><#t>
			<#if col.defaultValue??> DEFAULT ${col.defaultValue}</#if><#t>
			<#if col.unique!false> UNIQUE</#if><#t>
		</#if>
		<#if col.comment??> COMMENT '${col.comment}'</#if>;<#lt>
	</#list>
</#if>
<#--删除字段， `删除`放到`新增`的下面，避免既有添加又有删除的时候，因为删除所有字段，导致数据库抛出异常-->
<#if dropColumns??>
	<#list dropColumns as col>
		ALTER TABLE ${tableName} DROP COLUMN ${col};<#lt>
	</#list>
</#if>
<#--删除主键-->
<#if (primaryKey.drop)?? && primaryKey.drop>
	ALTER TABLE ${tableName} DROP PRIMARY KEY;<#lt>
</#if>
<#--新增主键-->
<#if (primaryKey.parts)??>
	ALTER TABLE ${tableName} ADD PRIMARY KEY (<#t>
		<#list primaryKey.parts as part>
			${part.column}<#sep>, </#sep><#t>
		</#list>
	);<#lt>
</#if>
<#--修改字段-->
<#if alterColumns??>
<#list alterColumns as col>
	<#assign alterAttrs=col.alterAttributes>
	<#assign originAttrs=col.originAttributes>
	<#assign attrs=col.attributes>
	<#assign isVarchar = originAttrs.dbType=="VARCHAR"||originAttrs.dbType=="CHAR"||originAttrs.dbType=='LONGTEXT'>
	<#if alterAttrs.autoInc!false>
		<#--修改自增长-->
		ALTER TABLE ${tableName} MODIFY ${originAttrs.name} BIGINT NOT NULL AUTO_INCREMENT<#t>
		<#if (originAttrs.comment)?? && !(attrs.comment)??> COMMENT ''<#elseif (alterAttrs.comment)??> COMMENT '${alterAttrs.comment}'<#elseif (originAttrs.comment)??> COMMENT '${originAttrs.comment}'</#if>;<#lt>
	<#elseif alterAttrs.originalName??>
		<#--字段更名-->
		ALTER TABLE ${tableName} CHANGE ${alterAttrs.originalName} ${alterAttrs.name} ${originAttrs.typeDeclaration}<#if isVarchar> BINARY</#if><#t>
		<#if !originAttrs.nullable!true> NOT NULL</#if><#t>
		<#if originAttrs.defaultValue??> DEFAULT ${originAttrs.defaultValue}</#if><#t>
		<#if originAttrs.unique!false> UNIQUE</#if><#t>
		<#if (originAttrs.comment)??> COMMENT '${originAttrs.comment}'</#if>;<#lt>
	<#elseif alterAttrs.typeDeclaration??>
		<#--更改字段类型-->
		ALTER TABLE ${tableName} MODIFY ${originAttrs.name} ${alterAttrs.typeDeclaration}<#if alterAttrs.dbType=="VARCHAR"||alterAttrs.dbType=="CHAR"> BINARY</#if><#t>
		<#if (alterAttrs.nullable)??><#if !alterAttrs.nullable> NOT NULL</#if><#else><#if !originAttrs.nullable!true> NOT NULL</#if></#if><#t>
		<#if (alterAttrs.defaultValue)??> DEFAULT ${alterAttrs.defaultValue}<#else><#if originAttrs.defaultValue??> DEFAULT ${originAttrs.defaultValue}</#if></#if><#t>
		<#if (alterAttrs.unique)??><#if alterAttrs.unique> UNIQUE</#if><#else><#if originAttrs.unique!false> UNIQUE</#if></#if><#t>
		<#if (originAttrs.comment)?? && !(attrs.comment)??> COMMENT ''<#elseif (alterAttrs.comment)??> COMMENT '${alterAttrs.comment}'<#elseif (originAttrs.comment)??> COMMENT '${originAttrs.comment}'</#if>;<#lt>
	<#else>
		<#--修改字段属性，比如长度，nullable，defaultValue，unique，comment-->
		ALTER TABLE ${tableName} MODIFY ${originAttrs.name} ${originAttrs.typeDeclaration}<#if isVarchar> BINARY</#if><#t>
		<#if (alterAttrs.nullable)??><#if !alterAttrs.nullable> NOT NULL</#if><#else><#if !originAttrs.nullable!true> NOT NULL</#if></#if><#t>
		<#if (alterAttrs.defaultValue)??> DEFAULT ${alterAttrs.defaultValue}<#else><#if originAttrs.defaultValue??> DEFAULT ${originAttrs.defaultValue}</#if></#if><#t>
		<#if (alterAttrs.unique)??><#if alterAttrs.unique> UNIQUE</#if><#else><#if originAttrs.unique!false> UNIQUE</#if></#if><#t>
		<#if (originAttrs.comment)?? && !(attrs.comment)??> COMMENT ''<#elseif (alterAttrs.comment)??> COMMENT '${alterAttrs.comment}'<#elseif (originAttrs.comment)??> COMMENT '${originAttrs.comment}'</#if>;<#lt>
	</#if>
</#list>
</#if>
<#--删除索引-->
<#if dropIndexes??>
	<#list dropIndexes as index>
		DROP INDEX ${index} ON ${tableName};<#lt>
	</#list>
</#if>
<#--新增索引-->
<#if newIndexes??>
	<#list newIndexes as index>
		CREATE<#if index.unique!false> UNIQUE</#if> INDEX ${(index.name)!("IDX_AUTO_NAME_" + index?index)} ON ${tableName} (<#t>
			<#list index.parts as part>
				${part.column}<#sep>, </#sep><#t>
			</#list>
		);<#lt>
	</#list>
</#if>
```

### SQL参数模板{#sql-template-parameters}

#### tableName{#tablename}

目标数据表表名。

#### tableType{#tabletype}

数据库表类型，具体类型如下所示：

- `TABLE`：物理表，可以select和update数据
- `LOCAL_TEMPTABLE`：本地临时表，只在当前连接可见，当前连接物理关闭时删除
- `GLOBAL_TEMPTABLE`：全局临时表，所有连接可见，通常是引用过它的连接关闭时自动删除

#### originAttributes{#originattributes}

数据库表修改前的表属性，包括表注释，存储引擎，分布列等属性。

- `catalog`：
- `schema`：数据库表所在schema
- `tableName`：目标数据表表名。
- `mixedCase`：查询表时是否需要转义，为true表示此表的大小写和数据库标准不一致，需要进行转义。
- `tableType`：返回数据表的类型，具体可参考
- `tableComment`：返回表的注释，没有注释时返回`null`。
- `distributionColumns`：当目标数据库是分布式存储数据库时，返回分布字段的名称。
- `primaryKeys`：返回主键的值，没有时返回`null`。
- `indexes`：返回索引列表。
- `columns`：返回全部字段列表。

#### alterAttributes{#alterattributes}

返回修改后数据表的属性，结构同[originAttributes](#originattributes)，未修改的属性没有值。

#### attributes{#attributes}

返回修改后的完整的表属性，结构同[originAttributes](#originattributes)。

#### newColumns{#newcolumns}

新增字段的字段列表，是一个数组对象，每个元素都是一个字段，字段属性和[createtable-columns](/dev/extension-points/dbConnector/createtable/#columns)中的字段对象一致。

#### dropColumns{#dropcolumns}

需要删除的字段列表，是一个字段名数组。

#### alterColumns{#altercolumns}

需要修改的字段列表，包含了字段需要修改的所有信息，是一个对象数组。

属性如下：

- [alterAttributes](#alterattributes)
- [originAttributes](#originattributes)
- [attributes](#attributes)

#### primarKey{#primarkey}

若SQL模板中存在此属性，表示主键有修改，此对象和索引对象可以访问的属性一致，并新增一下2个属性：

- `drop`：为true表示需要删除原主键，如果原来的表有主键，但是新主键是不同的字段，需要先`drop`掉原来的主键。
- `columns`：新主键的字段列表。

#### newIndexes{#newindexes}

新增的索引，是一个数组对象，每一个元素都是一个索引，可访问的属性参考[createtable-indexes](/dev/extension-points/dbConnector/createtable/#indexes)。

#### dropIndexes{#dropindexes}

要删除的索引列表，是一个数组对象，每个元素都是要删除的索引名称。
