我们遇到了一个恼人的问题。 这个任务听起来很简单: 我们的客户需要更大的项目编号。该应用程序只需要在UI-Validation中进行一些小的更改。到目前为止,很好。
项目编号可以是字母数字,所以在我们的数据库中,数字字段是nvarchar(8) - 很糟糕,它也是项目的主要关键 - 不要问我,谁有这个可怕的想法...
因为它是主键,项目属于我们应用程序中最基本的对象,所以我们得到了许多引用该愚蠢项目编号的外键。
从客户到客户,引用表的数量并不是很稳定 - 因为少数客户激活了较少的模块,因此他们无法获得我们的应用程序可能拥有的所有表。
所以我们决定(在我们幼稚的思想中),我们编写一些简单的脚本/存储过程,将列的长度及其所有引用从nvarchar(8)更改为nvarchar(16)或类似的东西。
可悲的是,由于外键,SQL服务器呻吟,依赖于表。快速谷歌搜索导致
execute ('alter table [' + @tschema + '].[' + @tname + '] nocheck constraint all');
那应该停用外键,暂时,我们想扩展项目编号。
SQl服务器仍然给我们这些错误:
... Msg 5074,Level 16,State 1,Line 3 Das Objekt-Objekt 'PK_tblAnlagenProjekt'是Spalte-Objekt'ProjektNr'abhängig。消息 5074,Level 16,State 1,Line 3 Das Objekt-Objekt 'FK_tblAnlagenProjekt_tblProjekte'thet vom Spalte-Objekt'ProjektNr' abhängig。 ...所有表都会出现相同的错误 ...
我们当前的存储过程:
ALTER PROCEDURE [dbo].[ChangeProjektNrLength] @ProjektNrLength int
as
BEGIN
/* Disable foreign checks*/
declare @tname varchar(128), @tschema varchar(128);
declare tables cursor for
select TABLE_SCHEMA, TABLE_NAME
from INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'tbl%';
open tables;
fetch next from tables
into @tschema, @tname;
while @@FETCH_STATUS = 0
begin
execute ('alter table [' + @tschema + '].[' + @tname + '] nocheck constraint all');
fetch next from tables
into @tschema, @tname;
end;
close tables;
deallocate tables;
/* Change column length */
DECLARE @TableName nvarchar(max)
DECLARE c1 CURSOR READ_ONLY
FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE 'ProjektNr'
AND TABLE_NAME NOT LIKE '%view%'
ORDER BY TABLE_NAME ASC
OPEN c1
FETCH NEXT FROM c1
INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SQL varchar(1000)
SELECT @SQL = 'ALTER TABLE ' + @TableName + ' ALTER COLUMN ProjektNr nvarchar(' + CAST(@ProjektNrLength as varchar) + ')'
EXEC (@SQL)
PRINT 'Changed Length of ProjektNr in table ' + @TableName + ' to ' + CAST(@ProjektNrLength as varchar)
FETCH NEXT FROM c1
INTO @TableName
END
CLOSE c1
DEALLOCATE c1
/* Enable foreign checks*/
declare @tname2 varchar(128), @tschema2 varchar(128);
declare tables cursor for
select TABLE_SCHEMA, TABLE_NAME
from INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'tbl%';
open tables;
fetch next from tables
into @tschema2, @tname2;
while @@FETCH_STATUS = 0
begin
execute ('alter table [' + @tschema2 + '].[' + @tname2 + '] check constraint all');
fetch next from tables
into @tschema2, @tname2;
end;
close tables;
deallocate tables;
END
当我们在设计人员的帮助下直接在Microsoft SQL Management Studio中更改列长度并取消选中“防止保存需要重新创建表的更改”选项时,工作室告诉我们,其他表和如果我们也想改变它们 - 它会做到。但是我们搜索一下,不要手动改变所有~50个表的长度...如果我们错过了一些引用的列,我们可能会在生产时产生一些坏的应用程序错误。
有没有人给我们一些有用的提示?