ALTER TABLE的用法 增加列、删除列、改列名、改列约束、改表名

本文详细介绍了 SQL 中 ALTER TABLE 语句的使用方法,包括如何添加、重命名列和表,设置默认值,以及添加约束等。同时提供了示例说明如何执行这些操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ALTER TABLE
名称
ALTER TABLE — 更改表属性
语法
ALTER TABLE table [ * ]
    
ADD [ COLUMN ] column type
ALTER TABLE table [ * ]
    
ALTER [ COLUMN ] column { SET DEFAULT value | DROP DEFAULT }
ALTER TABLE table [ * ]
    RENAME 
[ COLUMN ] column TO newcolumn
ALTER TABLE table
    RENAME 
TO newtable
ALTER TABLE table
    
ADD table constraint definition
Inputs
table 
试图更改的现存表的名称. 
column 
现存或新的列名称. 
type 
新列的类型. 
newcolumn 
现存列的新名称. 
newtable 
表的新名称. 
table constraint definition 
表的新的约束定义. 
New 
table constraint for the table

输出
ALTER 
从被更名的列或表返回的信息. 
ERROR 
如果一个列或表不存在返回的信息.
描述
ALTER TABLE 变更一个现存表的定义.ADD COLUMN 形式用与 CREATE TABLE一样的语法向表中增加一个新列/字段。ALTER COLUMN 形式允许你从列/字段中设置或者删除缺省(值)。注意缺省(值)只对新插入的行有效。RENAME 子句可以在不影响相关表中任何数据的情况下更改一个表或者列/字段的名称。因此,表或列/字段在此命令执行后仍将是相同尺寸和类型。ADD table constraint definition 子句用与 CREATE TABLE一样的语法向表中增加一个新的约束。 

如果要改变表的属性,你必须是表的所有者.

注意
COLUMN 关键字是多余的,可以省略. 
如果"
*"跟在一个表名后面,表示该命令要对该表和所有继承级别低于该表的表进行操作;缺省时,该属性(更改)不会增加到任何子表或修改任何子表的相关名称。当增加或修改一个上级表(译注:继承级别高的表)的属性时总是应该这样的。否则,象下面这样的在继承级上进行的查询 
SELECT NewColumn FROM SuperClass*
将不能工作,因为子表会比上级表少一个属性。 
在目前的实现里,新列
/字段的缺省(值)和约束子句会被忽略。你可以随后用 ALTER TABLE 的 SET DEFAULT 形式设置缺省(值)。(你还不得不用 UPDATE 把已存在行更新为缺省值。)

在目前的实现里,只有 
FOREIGN KEY 约束可以增加到表中.要创建或者删除一个唯一约束,可以创建一个唯一索引(参阅 CREATE INDEX).要想增加 check (检查)约束,你需要重建和重载该表,用的参数是 CREATE TABLE 命令的其他参数.
要修改表的结构,你必须是表的所有人。不允许更改系统表结构的任何部分。PostgreSQL 用户手册 里有关于继承的更多信息. 

用法
向表中增加一个 
VARCHAR 列: 
ALTER TABLE distributors ADD COLUMN address VARCHAR(30);
对现存列改名: 
ALTER TABLE distributors RENAME COLUMN address TO city;
对现存表改名: 
ALTER TABLE distributors RENAME TO suppliers;
向表中增加一个外键约束: 
ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses(address) MATCH FULL

兼容性
SQL92ADD 
COLUMN 形式是兼容的,除了上面说的缺省(值)和约束外。ALTER COLUMN 形式是完全兼容的。 
SQL92 对 
ALTER TABLE 声明了一些附加的Postgres目前还不直接支持的功能:
ALTER TABLE table DROP CONSTRAINT constraint { RESTRICT | CASCADE }
增加或删除表的约束(比如象检查约束,唯一约束或外键约束)。要创建或删除一个唯一约束,对应地创建或删除一个唯一索引,要修改其他类型的约束,你需要重建和重载该表,使用 
CREATE TABLE  命令的其他参数. 
例如,删除表 distributors 的任何约束: 
CREATE TABLE temp AS SELECT * FROM distributors;
DROP TABLE distributors;
CREATE TABLE distributors AS SELECT * FROM temp;
DROP TABLE temp;
ALTER TABLE table DROP [ COLUMN ] column { RESTRICT | CASCADE }
前,要删除一个现存的列,表必须重新创建和重新装载: 
CREATE TABLE temp AS SELECT did, city FROM distributors;    
DROP TABLE distributors;
CREATE TABLE distributors (
    did      
DECIMAL(3DEFAULT 1,
    name     
VARCHAR(40NOT NULL,
);
INSERT INTO distributors SELECT * FROM temp;
DROP TABLE temp;
重命名列
/字段和表名是 PostgreSQL 扩展。SQL92 没有提供这些。

<think>我们正在讨论MSSQL属性失败的问题。根据之前的对话历史,用户尝试修列名时遇到“不允许修”的提示,我们已经给出了多种解决方法。现在用户的新问题是关于修属性(例如数据类型、长度等)失败。 结合引用[3]中提到的MySQL字段属性不起作用的例子(虽然环境不同,但原理可参考),以及MSSQL的特点,我们分析可能的原因和解决方案。 常见原因: 1. 表被锁定(有活动事务或查询正在使用该表) 2. 存在约束(如主键、外键、检查约束、默认值约束等) 3. 被索引或统计信息依赖 4. 有依赖对象(如视图、存储过程、函数等) 5. 修后的属性与现有数据冲突(如将varchar(10)为varchar(5),但已有数据长度大于5) 6. 权限不足 解决方案: 方法1:检查表是否被锁定 使用以下查询检查锁定状态,并终止阻塞会话(谨慎使用): ```sql SELECT request_session_id, resource_type, request_status FROM sys.dm_tran_locks WHERE resource_associated_entity_id = OBJECT_ID('表名'); -- 如果发现阻塞,可以终止会话(确保不影响生产) KILL [session_id]; ``` 方法2:检查并处理约束 如果有约束(如默认值约束),需要先删除约束,再修属性,最后重新添加约束。 步骤: 1. 查找约束: ```sql SELECT dc.name AS constraint_name, dc.definition FROM sys.default_constraints dc WHERE parent_object_id = OBJECT_ID('表名') AND parent_column_id = COLUMN_ID('列名'); -- 其他约束(如检查约束): SELECT cc.name AS constraint_name, cc.definition FROM sys.check_constraints cc WHERE parent_object_id = OBJECT_ID('表名') AND parent_column_id = COLUMN_ID('列名'); ``` 2. 删除约束: ```sql ALTER TABLE 表名 DROP CONSTRAINT 约束名; ``` 3. 修属性: ```sql ALTER TABLE 表名 ALTER COLUMN 列名 新数据类型 [新属性]; -- 示例:将的数据类型为varchar(50)且非空 ALTER TABLE student4 ALTER COLUMN sname VARCHAR(50) NOT NULL; ``` 4. 重建约束(如果需要): ```sql ALTER TABLE 表名 ADD CONSTRAINT 约束名 DEFAULT (默认值) FOR 列名; ``` 方法3:处理索引依赖 如果上有索引(包括主键/唯一约束的索引),可能需要先删除索引,修后再重建索引。 步骤: 1. 查找索引: ```sql EXEC sp_helpindex '表名'; -- 或 SELECT i.name AS index_name, i.type_desc, c.name AS column_name FROM sys.indexes i JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE i.object_id = OBJECT_ID('表名') AND c.name = '列名'; ``` 2. 删除索引(注意主键约束需要先删除约束): ```sql DROP INDEX 索引名 ON 表名; -- 如果是主键约束 ALTER TABLE 表名 DROP CONSTRAINT 主键约束名; ``` 3. 修属性。 4. 重建索引(或主键约束): ```sql CREATE INDEX 索引名 ON 表名(列名); -- 或主键 ALTER TABLE 表名 ADD CONSTRAINT 主键约束名 PRIMARY KEY (列名); ``` 方法4:处理数据兼容性问题 修的数据类型时,要确保现有数据可以隐式转换为新类型。如果不确定,可以先创建一个临时,将数据转换后复制过去,再删除并重命名临时。 步骤: ```sql -- 1. 添加临时 ALTER TABLE 表名 ADD 临时列名 新数据类型; -- 2. 更新临时(转换数据) UPDATE 表名 SET 临时列名 = CAST(原列名 AS 新数据类型); -- 3. 删除 ALTER TABLE 表名 DROP COLUMN 原列名; -- 4. 重命名临时为原列名 EXEC sp_rename '表名.临时列名', '原列名', 'COLUMN'; ``` 方法5:使用SSMS设计器并禁用“阻止保存更”选项 步骤: 1. 打开SSMS -> 工具 -> 选项 2. 设计器 -> 表设计器和数据库设计器 -> 取消勾选“阻止保存要求重新创建表的更” 3. 重新打开表设计器修属性 方法6:检查权限 确保当前用户有ALTER权限: ```sql -- 授予权限(需要权限) GRANT ALTER ON 表名 TO 用户名; ``` 方法7:处理依赖对象 如果被视图、存储过程等引用,需要先修这些对象,或者暂时删除再重建。可以使用以下查询查找依赖: ```sql SELECT referencing_schema_name, referencing_entity_name, referencing_class_desc FROM sys.dm_sql_referencing_entities('表名', 'OBJECT'); ``` 注意:修属性可能影响应用程序,请在维护窗口操作,并备份数据。 最后,修属性后,建议运行以下命令检查表: ```sql DBCC CHECKTABLE ('表名'); ``` 引用[3]中提到,在MySQL中修字段属性时,要注意数据类型的定义(如decimal(M,D))和现有数据的兼容性,这在MSSQL中同样适用。 生成相关问题: 1. MSSQL中如何修带有外键约束的的数据类型? 2. 如何避免修表结构时导致的生产环境停机? 3. MSSQL中如何批量修多个的属性? 4. 修属性后如何验证数据完整性?</think>### MSSQL属性失败的原因及解决方法 在 MSSQL 中修属性(如数据类型、长度、精度等)失败通常由以下原因导致,以下是系统化的解决方案: --- #### 常见错误场景及解决方案 1. **数据类型冲突错误** ```sql -- 错误示例:将 varchar(10) 为 varchar(5) 但存在更长的数据 ALTER TABLE Orders ALTER COLUMN ProductName VARCHAR(5) NOT NULL; ``` **解决方法**: ```sql -- 1. 检查数据兼容性 SELECT MAX(LEN(ProductName)) FROM Orders; -- 2. 临时扩大长度再缩小 ALTER TABLE Orders ALTER COLUMN ProductName VARCHAR(100) NULL; UPDATE Orders SET ProductName = LEFT(ProductName, 5); ALTER TABLE Orders ALTER COLUMN ProductName VARCHAR(5) NOT NULL; ``` 2. **存在约束依赖** ```sql -- 错误:有默认值约束时修失败 ALTER TABLE Users ALTER COLUMN CreateDate DATETIME2; ``` **解决方法**: ```sql -- 1. 查找约束 SELECT name FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID('Users') AND parent_column_id = COLUMN_ID('CreateDate'); -- 2. 删除约束 ALTER TABLE Users DROP CONSTRAINT DF_Users_CreateDate; -- 3. 修属性 ALTER TABLE Users ALTER COLUMN CreateDate DATETIME2; -- 4. 重建约束 ALTER TABLE Users ADD CONSTRAINT DF_Users_CreateDate DEFAULT GETDATE() FOR CreateDate; ``` 3. **表被锁定或事务阻塞** **解决方法**: ```sql -- 检查锁定状态 SELECT request_session_id, resource_type, request_status FROM sys.dm_tran_locks WHERE resource_associated_entity_id = OBJECT_ID('YourTable'); -- 终止阻塞会话 (谨慎使用) KILL [session_id]; ``` 4. **精度修冲突** ```sql -- 错误:decimal(10,2) 为 decimal(8,4) 但存在 123.456 的值 ALTER TABLE Products ALTER COLUMN Price DECIMAL(8,4); ``` **解决方法**: ```sql -- 1. 检查数据范围 SELECT MIN(Price), MAX(Price) FROM Products; -- 2. 临时扩大精度 ALTER TABLE Products ALTER COLUMN Price DECIMAL(12,6); -- 3. 调整数据 UPDATE Products SET Price = ROUND(Price, 4); -- 4. 最终修 ALTER TABLE Products ALTER COLUMN Price DECIMAL(8,4); ``` --- #### 通用操作流程 ```mermaid graph TD A[修属性失败] --> B{检查错误类型} B -->|数据类型冲突| C[检查数据兼容性] B -->|约束依赖| D[处理约束] B -->|表锁定| E[解除锁定] C --> F[临时扩大范围] D --> G[删除约束] G --> H[修属性] H --> I[重建约束] E --> J[终止阻塞会话] F --> H J --> H I --> K[操作成功] H --> K ``` --- #### 高级技巧:通过临时表修 当直接修失败时: ```sql BEGIN TRANSACTION -- 创建新结构表 CREATE TABLE Products_new ( ID INT PRIMARY KEY, ProductName VARCHAR(100), Price DECIMAL(10,4) -- 新精度 ); -- 迁移数据 INSERT INTO Products_new (ID, ProductName, Price) SELECT ID, ProductName, CAST(Price AS DECIMAL(10,4)) FROM Products; -- 切换表 EXEC sp_rename 'Products', 'Products_old'; EXEC sp_rename 'Products_new', 'Products'; -- 重建索引/约束 ALTER TABLE Products ADD CONSTRAINT PK_Products PRIMARY KEY (ID); COMMIT TRANSACTION ``` --- #### 预防措施 1. **操作前检查**: ```sql -- 检查依赖 EXEC sp_depends @objname = 'YourTable.YourColumn'; -- 检查数据分布 SELECT MIN(column), MAX(column), MAX(LEN(column)) FROM YourTable; ``` 2. **使用事务保证回滚**: ```sql BEGIN TRY BEGIN TRANSACTION ALTER TABLE ... -- 修操作 COMMIT TRANSACTION END TRY BEGIN CATCH ROLLBACK TRANSACTION PRINT 'Error: ' + ERROR_MESSAGE() END CATCH ``` > 📌 **关键提示**: > - 修 `IDENTITY` 需使用 `SET IDENTITY_INSERT ON/OFF` > - 修主键/外键需先删除约束 > - 生产环境操作前务必备份数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值