我正在处理SQL Server 2012
:
我有一个主键列为INT
的表。我需要将其更改为 GUID 。
我是否更改了表并将int列移除为primary key
?
添加 GUID 列并将其设置为主要并删除旧的INT列?
谢谢。
答案 0 :(得分:12)
您无法更改主键列,除非您删除它。任何更改其数据类型的操作都将导致以下错误..
对象'XXXX'依赖于列'XXXX'。
只有选项
1.Drop主键
2.更改数据类型
3.recreate primary key
ALTER TABLE t1
DROP CONSTRAINT PK__t1__3213E83F88CF144D;
GO
alter table t1
alter column id varchar(10) not null
alter table t1 add primary key (id)
从2012年起,有一个名为(DROP_EXISTING = ON)
的子句,通过在最后阶段删除聚簇索引并保持旧索引可用于所有操作,使事情变得简单。但在您的情况下,此子句不会工作..
所以我建议
1.使用不同的名称来创建具有所需模式和索引的新表 2.将旧表中的数据插入新表中 3.在切换时,插入累积的数据 4.将表重命名为旧表名
这样可以减少停机时间
答案 1 :(得分:3)
您可以分三步更改主键的日期类型
步骤1:-删除与主键相关联的约束
ALTER TABLE table_name
DROP CONSTRAINT constraint_name;
第2步:-将Primay键列更改为有效的主键数据类型
ALTER TABLE table_name
ALTER COLUMN pk_column_name target_data_type(size) not null;
步骤3:-再次将更改后的列作为主键
ALTER TABLE table_name
ADD PRIMARY KEY (pk_column_name);
PS:-
当您尝试更改密码时,可以从错误消息中获取约束名称。 pk_column
如果pk_column中已经有数据,请确保该列的源和目标数据类型都可以用于现有数据。否则,将需要另外两个步骤将现有数据移至临时列,然后执行这些步骤,并在审核并删除该临时列后恢复该数据。
答案 2 :(得分:1)
下面是我编写的脚本,用于帮助我们将更改部署到主键列数据类型。
此脚本假定没有任何非主键约束(例如外键),具体取决于此列。
它有一些安全检查,因为它被设计为部署到不同的服务器(dev,uat,live)而不会产生副作用,如果表在服务器上有所不同。
我希望这有助于某人。如果您在投票前发现任何问题,请告诉我。我非常乐意更新脚本。
IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS C WITH (NOLOCK) WHERE C.TABLE_CATALOG = '<<DB>>' AND C.TABLE_SCHEMA = 'dbo' AND C.TABLE_NAME = '<<Table>>'
AND C.COLUMN_NAME = '<<COLUMN>>' AND C.DATA_TYPE = 'int') -- <- Additional test to check the current datatype so this won't make unnecessary or wrong updates
BEGIN
DECLARE @pkName VARCHAR(200);
SELECT @pkName = pkRef.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pkRef WITH (NOLOCK)
WHERE pkRef.TABLE_CATALOG = '<<DB>>' AND pkRef.TABLE_SCHEMA = 'dbo' AND TABLE_NAME = '<<Table>>'
IF(@pkName IS NOT NULL)
BEGIN
-- Make sure the primary key name is the one you are going to use in script beyond this point.
IF(@pkName != '<<PRIMARY KEY NAME>>')
BEGIN
RAISERROR ('Unexpected primary key name - The primary key found has a different name than expected. Please update the script.', 16, 1);
RETURN;
END
ALTER TABLE dbo.<<Table>>
DROP CONSTRAINT <<PRIMARY KEY NAME>>; -- Note: this is not a string or a variable (just type the PK name)
SELECT 'Dropped existing primary key';
END
ALTER TABLE dbo.<<Table>> ALTER COLUMN ID BIGINT
SELECT 'Updated column type to big int';
ALTER TABLE dbo.<<Table>>
ADD CONSTRAINT <<PRIMARY KEY NAME>> PRIMARY KEY CLUSTERED (<<COLUMN>>);
SELECT 'Created the primary key';
END
ELSE
BEGIN
SELECT 'No change required.';
END
答案 3 :(得分:0)
如果其他表引用了带有索引FK的PK,则必须遵循这些步骤。
在此示例中,主表称为Main
,即单个引用表Reference
。我将数据类型更改为NVARCHAR(7)
。要使用它:
dbo
模式; ALTER TABLE dbo.Main ADD IdNew NVARCHAR(7);
UPDATE dbo.Main SET IdNew = Id;
-- For all tables with FK's to this Main
ALTER TABLE dbo.Reference ADD MainIdNew NVARCHAR(7);
UPDATE dbo.Reference SET MainIdNew = MainId;
ALTER TABLE dbo.Reference DROP CONSTRAINT FK_Reference_MainId_Asset_Id;
DROP INDEX IX_Reference_MainId ON dbo.Reference;
ALTER TABLE dbo.Reference DROP COLUMN MainId;
-- Until here
ALTER TABLE dbo.Main DROP CONSTRAINT PK_Asset;
ALTER TABLE dbo.Main DROP COLUMN Id;
-- Again for all tables with FK's to this Main
EXEC sp_rename 'dbo.Main.IdNew', 'Id', 'COLUMN';
ALTER TABLE dbo.Main ALTER COLUMN Id NVARCHAR(7) NOT NULL;
ALTER TABLE dbo.Main ADD CONSTRAINT PK_Asset PRIMARY KEY (Id);
EXEC sp_rename 'dbo.Reference.MainIdNew', 'MainId', 'COLUMN';
ALTER TABLE dbo.Reference ADD CONSTRAINT FK_Reference_MainId_Asset_Id FOREIGN KEY (MainId) REFERENCES dbo.Main(Id);
CREATE INDEX IX_Reference_MainId ON dbo.Reference(MainId);
答案 4 :(得分:-1)
在表中,您要更改PK类型>>修改。进入列,更改类型并保存。如果要查看更改的代码,请在保存之前右键单击>>“ Generate Change Script ..”。
答案 5 :(得分:-1)