我有一个用户定义的类型,其中需要增加一个VARCHAR列的大小。由于依赖性(使用该类型的存储过程),因此无法更改类型。所以,我尝试了以下内容:
这是场景:
T_MyType
重命名为T_MyType_1
,T_MyType_1
类型构建创建脚本,_1
”并增加一个字段的大小,然后运行脚本,T_MyType_1
并得到错误声明该类型正被过程ABC使用,T_MyType_1
,找不到字符串。所以,我坚持使用需要删除的类型。
我相信这个问题与提议的重复问题不同。
重命名是一种危险的消遣,因为它不能很好地与SQL Server的依赖性跟踪的有限实现以及存储过程的延迟名称解析相匹配。我实际上无法在SQL Server 2017上重现此特定方案(如果在过程的主体中使用了UDT,则会正确跟踪依赖关系),因此这种情况可能已得到改进。当然,如果您使用UDT作为参数,它实际上会检测到问题并提供相应的错误消息:
CREATE TYPE BadUdt FROM NVARCHAR(10);
GO
CREATE PROCEDURE AreUdtsBadThough(@T BadUdt) AS BEGIN
RETURN;
END;
GO
EXEC sp_rename 'BadUdt', 'GoodUdt';
GO
CREATE TYPE BadUdt FROM NVARCHAR(20);
GO
EXEC AreUdtsBadThough NULL
消息496,级别16,状态1,过程AreUdtsBadThough,第6行[批处理开始行16]参数“@T”与创建它的类型不同。使用类型的两部分名称删除并重新创建模块,或使用sp_refreshsqlmodule刷新其参数元数据。
尽管名称发生了变化,但AreUdtsBadThough
的参数仍然通过ID链接到旧类型,这就是为什么你不能删除它:
SELECT p.[name], t.[name]
FROM sys.parameters p
JOIN sys.types t ON p.user_type_id = t.user_type_id
WHERE [object_id] = OBJECT_ID('AreUdtsBadThough')
+------+---------+
| name | name |
+------+---------+
| @T | GoodUdt |
+------+---------+
该错误有助于描述依赖性问题的一般解决方案:调用sp_refreshsqlmodule
,它强制有效地重新编译存储过程(或函数,触发器或视图)以及要更新的依赖项:
EXEC sp_refreshsqlmodule 'AreUdtsBadThough'
SELECT p.[name], t.[name]
FROM sys.parameters p
JOIN sys.types t ON p.user_type_id = t.user_type_id
WHERE [object_id] = OBJECT_ID('AreUdtsBadThough')
+------+--------+
| name | name |
+------+--------+
| @T | BadUdt |
+------+--------+
现在GoodUdt
已经没有依赖关系了,可以放弃。
依赖关系的问题并不总是正确更新(不限于重命名),这促使一些人提出了更永久的解决方案。由于改进了依赖性检查,Aaron Bertrand有一个article自动化SQL Server 2008的依赖项刷新(它应该仍适用于以后的版本,即使它可能做的工作多于必要的工作)。
我不会重命名一个对象。这通常不推荐,我知道它可能会导致问题。最有可能这是你问题的核心,我怀疑这背后有一些隐藏的映射。
一般情况下:如果没有ALTER
,则重命名将无用。
我建议找到所有依赖项,构建所需的drop并创建脚本,从而确保一切正常。所有这一切甚至可以通过一个脚本通过系统表提取你需要的脚本来完成。另一种方法是通过Generate Scripts命令查找依赖项并编写脚本,从而确保以正确的顺序生成脚本。