【问题标题】:Altering user-defined table types in SQL Server在 SQL Server 中更改用户定义的表类型
【发布时间】:2012-07-10 09:52:23
【问题描述】:

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

【问题讨论】:

标签: sql-server user-defined-types


【解决方案1】:

据我所知,不可能更改/修改表类型。您 可以创建具有不同名称的类型,然后删除旧类型 并将其修改为新名称

感谢jkrajes

根据msdn,就像'用户定义的表类型定义创建后不能修改'。

【讨论】:

  • 我根据用户定义的类型和用户定义的类型本身,使用一系列生成的所有对象的放置/创建脚本。
  • 如何在 sql 中得到 20,000+ 行脚本?删除/创建您需要更改的表类型的所有依赖项。 :P
  • 这太糟糕了(微软),现在每当我对这些表进行更改时,我都必须修改所有 sp,然后删除、重新创建并返回并更新对它们的任何引用。考虑不周..我知道这是在咆哮,但他们在想什么??
  • 此外,您甚至似乎也不允许更改用户定义的表类型的所有者。删除表类型并使用新的所有者名称再次创建它似乎是更改所有者名称的唯一方法,以防您需要修改它。 sp_changeobjectowner 不适用于用户定义的表类型...
【解决方案2】:

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

  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

警告:

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

【讨论】:

  • 在 MSDN 链接上对 sp_refreshsqlmodule 的评论:msdn.microsoft.com/en-us/library/bb326754.aspx 非常具有威胁性。但是这个SP是否也更新了引用对象的文本或者只是更新了编译形式。我的意思是,如果我将在我引用的一个 SP 上运行 SP_HELPTEXT,那么我会在那里获得新的类型名称吗?
  • 这不会将存储过程中的表类型更改为 z 表类型。它所做的一切都会刷新模式,但会修复对表类型的引用。如果您在重新创建表类型后没有在存储过程中运行sp_refreshsqlmodle,则存储过程将失败,说明表类型已更改。我确实建议在生产中运行它之前在你的数据库的开发版本上运行它。
  • 这个答案对我不起作用。一旦执行 sp_rename,SP 上的参数类型就会更新以引用新的 UDTT。然后稍后重命名的 UDTT 不能被删除。 sp_rename 强制执行依赖关系。此答案假定 sp_rename 不会在引用 SP 时更新参数类型。
  • sp_rename 在用户定义的数据类型上给我一个错误:Either the parameter @objname is ambiguous or the claimed @objtype ((null)) is wrong. 有什么问题?
  • @Muflix,您可能需要像 EXEC sys.sp_rename 'dbo.MyTableType', 'zMyTableType', 'OBJECT'; 这样传入对象类型。还要确保您包含第一个参数的架构,而不是第二个参数。
【解决方案3】:

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

请记住,您可以从“对象资源管理器详细信息”窗口为多个对象生成 DROP/CREATE 语句(以这种方式生成时,将 DROP 和 CREATE 脚本分组,这样可以轻松地在 Drop 和 Create 操作之间插入逻辑):

  1. 备份您的数据库,以防出现任何问题!
  2. 为所有依赖项自动生成 DROP/CREATE 语句(或为所有“可编程性”对象生成以消除查找依赖项的乏味)。
  3. 在 DROP 和 CREATE [dependencies] 语句之间(在所有 DROP 之后,在所有 CREATE 之前),插入生成的 DROP/CREATE [table type] 语句,使用 CREATE TYPE 进行所需的更改。
  4. 运行脚本,该脚本会删除所有依赖项/UDTT,然后重新创建 [UDTT 与更改]/依赖项。

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

要为多个对象生成 DROP/CREATE 语句,您可以右键单击数据库 > 任务 > 生成脚本...(如下面的屏幕截图所示)。注意:

  1. DROP 语句是之前 CREATE 语句
  2. DROP 语句按依赖顺序(即 CREATE 的逆向)
  3. CREATE 语句按依赖顺序

【讨论】:

  • 我听取了您的建议,并考虑迁移数十万行代码以使用实体框架,这样我们就可以避免不得不删除并重新创建用户定义的表类型。但是,一秒钟后,我决定删除并重新创建表格类型是目前比较容易的方法。
  • @PapillonUK,我和你在一起。我有一个更大的项目,所以我仍然和你做同样的决定(上面的方法太快了,在可预见的将来我可能会继续这样做)。我提到对于那些拥有较小项目的人来说,从现在更改架构以简化未来更改可能有意义的人远离 UDTT,因此我相应地更新了我的答案。谢谢。
【解决方案4】:

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

这样,删除和重新创建依赖对象由更改脚本处理。

【讨论】:

  • 我发现这个答案与 BioEcoSS 的答案一起很有帮助
【解决方案5】:

Simon Zeinstra 找到了解决方案!

但是,我使用了 Visual Studio 社区 2015,我什至不必使用架构比较。

使用 SQL Server 对象资源管理器,我在数据库中找到了我的用户定义表类型。我用鼠标右键单击表格类型并选择了 .这会在 IDE 中打开一个代码选项卡,其中 TSQL 代码可见且可编辑。我只是更改了定义(在我的例子中只是增加了 nvarchar 字段的大小)并单击了选项卡左上角的 Update Database 按钮。

嘿Presto! - 快速检查 SSMS 并修改了 udtt 定义。

太棒了 - 谢谢西蒙。

【讨论】:

  • 这可能更适合作为对答案的评论,而不是其本身的答案。
  • TBH 我发现这非常有用,是为我解决这个问题的简单途径,向像我这样不太熟悉 Visual Studio 中的数据库项目的人解释了如何做到这一点。跨度>
  • 我也发现这个答案很有帮助
  • 感谢分享这个=D
【解决方案6】:

您应该删除旧表类型并创建一个新表类型。但是,如果它有任何依赖项(任何使用它的存储过程),您将无法删除它。我已经posted another answer 介绍了如何自动化临时删除所有存储过程、修改表表然后恢复存储过程的过程。

【讨论】:

  • 它不是有依赖关系的,否则你为什么要从一开始就创建它?
  • @LarryBud - 一个简单的例子可能是如果有人刚刚创建它并且还没有机会在任何存储过程等中使用它。
【解决方案7】:

你不能改变/修改你的类型。您必须删除现有的并使用正确的名称/数据类型重新创建它或添加新列/s

【讨论】:

    【解决方案8】:

    只需在我的一个项目中更改用户定义的表类型即可。以下是我采用的步骤:

    1. 使用用户定义的表类型查找所有 SP。
    2. 为找到的所有 SP 保存一个创建脚本。
    3. 丢弃 SP。
    4. 为您希望更改的用户定义表保存一个创建脚本。 4.5 向用户定义的表类型添加额外的列或您需要的更改。
    5. 删除用户定义的表类型。
    6. 为用户定义的表类型运行创建脚本。
    7. 为 SP 运行创建脚本。
    8. 然后开始相应地修改 SP。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多