如何更改所有表中主键列的长度?

时间:2016-08-19 08:51:05

标签: sql-server

我们遇到了一个恼人的问题。 这个任务听起来很简单: 我们的客户需要更大的项目编号。该应用程序只需要在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个表的长度...如果我们错过了一些引用的列,我们可能会在生产时产生一些坏的应用程序错误。

有没有人给我们一些有用的提示?

0 个答案:

没有答案