SQL更改列类型取决于其他表[nvarchar到int(FK)]

时间:2017-08-29 08:09:40

标签: sql sql-server

我几个月前创建了一个数据库,实际上,这个架构非常糟糕。现在,我有近200万条记录,因为我没有在开始时正确构建数据库,所以请求很长。 在两张有关的表格之下:

表A:

id (PK, int)  
category (nvarchar)  
date (datetime)  

TableB

id (PK, int)  
category (nvarchar)  

我想将category列更改为“int”并在表之间创建关系(FK)。见下文:

表A:

id (PK, int)  
category (FK, int)  
date (datetime)  

键:PK_TableA,FK_TableB

我不问解决方案,而是建立脚本的一些提示: - 更改列 - 对于每条记录, 看看类别>取id>用id(int)

替换类别名称(字符串)

感谢您的帮助:)

2 个答案:

答案 0 :(得分:1)

我认为你可以从这样的事情开始。 最后,在检查之后(无论如何在更新之前备份您的表),您可以从tableA中删除CATEGORY列,并且(如果需要)重命名列CATEGORY_ID。 如果您愿意,在开始之前,您可以进行检查以供以后使用(参见最后):

SELECT CATEGORY, COUNT(*) AS RC
FROM TABLEA
GROUP BY CATEGORY;

示例脚本

CREATE TABLE TABLEA (ID INT, CATEGORY VARCHAR(20), DATE_A DATETIME);


CREATE TABLE TABLEB (ID INT, CATEGORY VARCHAR(20));

INSERT INTO TABLEA VALUES (1,'abc', GETDATE());
INSERT INTO TABLEA VALUES (2,'cde', GETDATE());
INSERT INTO TABLEA VALUES (3,'cde', GETDATE());
INSERT INTO TABLEA VALUES (4,'abc', GETDATE());
INSERT INTO TABLEA VALUES (5,'abc', GETDATE());
INSERT INTO TABLEA VALUES (6,'fgh', GETDATE());
INSERT INTO TABLEA VALUES (7,'zzz', GETDATE());

INSERT INTO TABLEB VALUES (100,'abc');
INSERT INTO TABLEB VALUES (200,'cde');
INSERT INTO TABLEB VALUES (300,'fgh');


SELECT * FROM TABLEA;

ALTER TABLE TABLEA ADD CATEGORY_ID INT;

UPDATE A SET CATEGORY_ID = B.ID
FROM TABLEA A 
LEFT JOIN TABLEB B ON A.CATEGORY = B.CATEGORY;


--CREATE INDEX TABLEA_CATID ON TABLEA (CATEGORY_ID);

SELECT CATEGORY_ID, COUNT(*) AS RC
FROM TABLEA
GROUP BY CATEGORY_ID;

为了简单起见,我没有添加PK(但是你知道它们是"必要的")。 我建议在TABLEA上为CATEGORY_ID定义FK约束。

答案 1 :(得分:1)

看看你如何命名你的列我说你想要一个新的列categoryid(FK,int)而不是TableA中的类别(nvarchar)。

获得此功能的简单方法是创建一个具有可空属性的新列,填充它,设置约束,删除可空属性并最后删除类别(varchar)列。如果您无法更改列名称,则需要添加一些额外的步骤来切换列。

由于你已经有两百万行,你最好创建一个新表(TableC),填充它并使用TableC切换TableA(删除/重命名TableA,重命名TableC TableA)。

表C:

id (PK, int)  
categoryid (FK, int)  
date (datetime)

在处理包含大量行的表时,通常最好不要创建新表并切换旧表。

关心马丁