在SQL Server中更改用户定义的表类型

yog*_*ogi 71 sql-server user-defined-types

如何在SQL Server中更改用户定义的表类型?

Man*_*jan 64

据我所知,无法更改/修改表类型.您可以使用不同的名称创建类型,然后删除旧类型并将其修改为新名称

积分jkrajes

根据msdn,它就像'用户定义的表类型定义在创建后无法修改'.

  • 这很糟糕(Microsoft),现在每当我对这些表进行更改时,我都必须修改所有sp,然后删除,重新创建并返回并更新对它们的任何引用.经过深思熟虑......我知道这是一个咆哮,但他们在想什么? (13认同)
  • 如何在sql中结束20,000多行脚本?删除/创建需要更改的表类型的所有依赖项.:P (5认同)
  • 我根据用户定义的类型以及用户定义的类型本身使用一系列生成的所有对象的拖放脚本。 (2认同)

nor*_*ndo 34

这是一种黑客攻击,但似乎确实有效.以下是修改表类型的步骤和示例.需要注意的是,如果对表类型所做的更改是对该对象(通常是过程)的重大更改,则sp_refreshsqlmodule将失败.

  1. 使用sp_rename重命名表的类型,我通常只是添加Z到名字的开头.
  2. 创建一个新的表类型,其中包含原始名称以及您需要对表类型进行的任何修改.
  3. 逐步执行每个依赖项并sp_refreshsqlmodule在其上运行.
  4. 删除重命名的表类型.

EXEC sys.sp_rename 'dbo.MyTableType', 'zMyTableType';
GO
CREATE TYPE dbo.MyTableType AS TABLE(
    Id INT NOT NULL,
    Name VARCHAR(255) NOT NULL
);
GO
DECLARE @Name NVARCHAR(776);

DECLARE REF_CURSOR CURSOR FOR
SELECT referencing_schema_name + '.' + referencing_entity_name
FROM sys.dm_sql_referencing_entities('dbo.MyTableType', 'TYPE');

OPEN REF_CURSOR;

FETCH NEXT FROM REF_CURSOR INTO @Name;
WHILE (@@FETCH_STATUS = 0)
BEGIN
    EXEC sys.sp_refreshsqlmodule @name = @Name;
    FETCH NEXT FROM REF_CURSOR INTO @Name;
END;

CLOSE REF_CURSOR;
DEALLOCATE REF_CURSOR;
GO
DROP TYPE dbo.zMyTableType;
GO
Run Code Online (Sandbox Code Playgroud)

警告:

这可能会破坏您的数据库,因此您首先需要在开发环境中对此进行测试.


And*_*ght 12

这里有一些简单的步骤可以最大限度地减少乏味,并且不需要容易出错的半自动脚本或昂贵的工具.

请记住,您可以从"对象资源管理器详细信息"窗口生成多个对象的DROP/CREATE语句(以这种方式生成时,DROP和CREATE脚本会进行分组,这使得在Drop和Create操作之间插入逻辑变得容易): 在此输入图像描述

  1. 如果出现任何问题,请备份数据库!
  2. 自动为所有依赖项生成DROP/CREATE语句(或为所有"可编程性"对象生成以消除查找依赖项的繁琐).
  3. 在DROP和CREATE [dependencies]语句之间(在所有DROP之后,在所有CREATE之前),插入生成的DROP/CREATE [表类型]语句,使用CREATE TYPE进行所需的更改.
  4. 运行脚本,删除所有依赖项/ UDTT,然后重新创建[具有更改的UDTT] /依赖项.

如果您的项目较小,可能需要更改基础架构体系结构,请考虑删除用户定义的表类型.实体框架和类似工具允许您将大部分(如果不是全部)数据逻辑移动到更容易维护的代码库中.

  • 我采纳了您的建议,并考虑迁移数十万行代码以使用实体框架,这样我们就可以避免删除并重新创建用户定义的表类型。但是,过了一会儿,我决定删除并重新创建表类型是目前更简单的方法。 (2认同)
  • @PapillonUK,我和你在一起。我有一个更大的项目,所以我仍然做出与你相同的决定(并且上面的方法是如此之快,以至于在可预见的未来我可能会继续这样做)。我提到过对于那些拥有较小项目的人来说,放弃 UDTT,因为现在更改架构以简化未来的更改可能是有意义的,因此我相应地更新了我的答案。谢谢。 (2认同)

小智 6

如果可以在Visual Studio中使用数据库项目,则可以在项目中进行更改,并使用架构比较将更改同步到数据库。

这样,更改脚本将处理删除和重新创建相关对象的过程。


Bor*_*ode 5

您应该删除旧的表类型并创建一个新的表类型。但是,如果它有任何依赖项(任何使用它的存储过程),您将无法删除它。我发布了另一个关于如何自动执行临时删除所有存储过程、修改表表然后恢复存储过程的过程的答案。


小智 5

Simon Zeinstra找到了解决方案!

但是,我使用了Visual Studio community 2015,甚至没有使用架构比较。

使用SQL Server Object Explorer,我在数据库中找到了用户定义的表类型。我右键单击表格类型并选择。这在IDE中打开了一个代码选项卡,其中TSQL代码可见且可编辑。我只是简单地更改了定义(就我而言,只是增加了nvarchar字段的大小),然后单击了选项卡左上角的“ 更新数据库”按钮。

嗨,普雷斯托!-快速检查SSMS并修改了udtt定义。

辉煌-感谢Simon。