我继承了一个有一些重要缺陷的数据库设计:核心表的主键(大约一半其他表引用,其中很多都有检查它的约束)是一个varchar(20)。
这令我感到困惑,但其背后的理由是明智的。数字(迄今为止,它们一直是数字)是两个数据字段的组合(保证在组合时是唯一的)但经常以一个或多个0开始。
我确信有更好的方法可以解决这个问题,但目前数据库架构的完全更改超出了范围。
问题是我们有一个新客户,其组合ID为25个字符。
当我们为这个客户的网站创建数据库时,我更新了所有字段。这花了我一天的大部分时间 - 我在表创建/修改级别上没有做过很多SQL,大约有25个表引用了这个字段(以及十几个或更多的存储过程,它们将其作为一个值参数),每个表都有许多必须删除的约束,以便可以编辑表。
总的来说,更新一个数据库花了我几乎整整一个工作日。这是漫长而枯燥的工作,但是一个错字可能会破坏数据库架构。我必须编写一个脚本,以正确的顺序从表中删除约束,更新所有字段,并重新添加所有约束。
有更简单的方法吗?我必须更改主键的字段长度,该主键也是20-25个表上的外键,我必须为大约8个不同的数据库执行此操作。这些约束在每个数据库上都有微妙的不同名称,因此我的脚本不适用于其他数据库。
答案 0 :(得分:1)
有两种方式。
不推荐且非常“侵入性”。
所有模式都存储在表sys
中,您可以在其中找到tables
,columns
和其他表。您必须准备一个UPDATE
查询来更改所需的值 - 这将直接影响表,模式,列和任何您想要的内容。
虽然没有人允许UPDATE / DELETE sys表,但这并不简单。有一些workarounds,但我没有自己尝试任何一种。
从数据库的信息架构中收集要更改的表:
SELECT 'ALTER TABLE ' + TABLE_NAME + ' ALTER COLUMN ' + COLUMN_NAME + ' ' + DATA_TYPE + '(100)' AS [Edit],
TABLE_NAME,
COLUMN_NAME,
CASE
WHEN CHARINDEX('numeric',DATA_TYPE) <> 0 THEN DATA_TYPE + '(' + CAST(NUMERIC_PRECISION AS varchar) + ', ' + CAST(NUMERIC_SCALE as varchar) + ')'
WHEN CHARINDEX('varchar',DATA_TYPE) <> 0 THEN DATA_TYPE + '(' + CAST(CHARACTER_MAXIMUM_LENGTH as varchar) + ')'
ELSE DATA_TYPE
END AS TYP
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE TABLE_NAME like '%'
AND TABLE_SCHEMA like '%'
AND CASE
WHEN CHARINDEX('numeric',DATA_TYPE) <> 0 THEN DATA_TYPE + '(' + CAST(NUMERIC_PRECISION AS varchar) + ', ' + CAST(NUMERIC_SCALE as varchar) + ')'
WHEN CHARINDEX('varchar',DATA_TYPE) <> 0 THEN DATA_TYPE + '(' + CAST(CHARACTER_MAXIMUM_LENGTH as varchar) + ')'
ELSE DATA_TYPE
END = 'varchar(50)'
调整,运行,复制[编辑]列并将其粘贴到SSMS中然后重新运行。