更改基础UDT时刷新表类型

时间:2019-01-29 09:56:04

标签: sql sql-server sql-server-2016

我正在尝试增加用户数据类型的长度。我正在采用以下方法:

  1. 将数据类型重命名为_old
  2. 创建具有相同名称但长度增加的数据类型。
  3. 为引用它们的SP和FN执行sp_refreshsqlmodule。

我无法考虑如何处理用户定义的表类型,因为无法使用sp_refreshsqlmodule更新它们的元。它们太多了,我无法手动为每种表类型编写drop和create。

搜索到的内容可能会发布,但不会成功,因此,如果您有任何想法,请发布答案。有人问了类似的question,但没有答案。

我正在发布代码段以供参考。 谢谢。

/****** DROP OBJECTS ******/
IF(OBJECT_ID('dbo.Test_SP',N'P') IS NOT NULL)
  DROP PROCEDURE dbo.Test_SP
GO

IF EXISTS(SELECT 1 FROM sys.table_types WHERE name = 'TestTableType' AND schema_id = SCHEMA_ID('dbo'))
  DROP TYPE dbo.TestTableType
GO

IF EXISTS(SELECT 1 FROM sys.types WHERE name = 'TestType_Old' AND schema_id = SCHEMA_ID('dbo'))
  DROP TYPE dbo.TestType_Old
GO

IF EXISTS(SELECT 1 FROM sys.types WHERE name = 'TestType' AND schema_id = SCHEMA_ID('dbo'))
  DROP TYPE dbo.TestType
GO
/**************************/

CREATE TYPE dbo.TestType FROM VARCHAR(30) NULL
GO

CREATE TYPE dbo.TestTableType AS TABLE (FullName dbo.TestType )
GO

CREATE PROCEDURE dbo.Test_SP (@FullName dbo.TestType)
AS
(
  SELECT  @FullName
)
GO

DECLARE @FN dbo.TestType

SET @FN = REPLICATE('A',30)

EXEC dbo.Test_SP  @FullName = @FN
GO


EXEC sp_rename N'dbo.TestType'
              ,N'TestType_Old'
              ,N'USERDATATYPE'
GO

CREATE TYPE dbo.TestType FROM VARCHAR(60) NULL
GO

DECLARE cur CURSOR FOR
SELECT  sch.name + N'.' + obj.name
FROM    sys.sql_expression_dependencies sed
        INNER JOIN sys.objects obj
          ON sed.referencing_id = obj.object_id
        INNER JOIN sys.schemas sch WITH(NOLOCK)
          ON sch.schema_id = obj.schema_id
WHERE   referenced_class_desc = 'TYPE' 
        AND referenced_entity_name IN(N'TestType',N'TestType_Old')
        AND referenced_schema_name = N'dbo'
UNION
SELECT  sch.name + N'.' + obj.name [ObjectName]
FROM    sys.columns col WITH(NOLOCK)
        INNER JOIN sys.objects obj WITH(NOLOCK)
          ON col.object_id = obj.object_id
        INNER JOIN sys.types typ WITH(NOLOCK)
          ON col.user_type_id = typ.user_type_id
        INNER JOIN sys.schemas sch WITH(NOLOCK)
          ON obj.schema_id = sch.schema_id
WHERE   typ.name IN(N'TestType',N'TestType_Old')
        AND typ.schema_id = SCHEMA_ID(N'dbo')
        AND is_ms_shipped = 0
        AND obj.type IN(N'TF','FS', 'IF');

OPEN cur;

DECLARE @ObjectName NVARCHAR(MAX);

FETCH NEXT FROM cur INTO @ObjectName;
WHILE(@@FETCH_STATUS = 0)
BEGIN
  PRINT @ObjectName;
  EXEC sp_refreshsqlmodule @name = @ObjectName;
  FETCH NEXT FROM cur INTO @ObjectName;
END;

CLOSE cur;
DEALLOCATE cur;
GO

DECLARE @FN dbo.TestType

SET @FN = REPLICATE('B',60)

EXEC dbo.Test_SP  @FullName = @FN
GO

--IF EXISTS(SELECT 1 FROM sys.table_types WHERE name = 'TestTableType' AND schema_id = SCHEMA_ID('dbo'))
--  DROP TYPE dbo.TestTableType
--GO

--CREATE TYPE dbo.TestTableType AS TABLE (FullName dbo.TestType )
--GO

--EXEC sp_refreshsqlmodule @name = 'TestTableType'; --TT_TestTableType_1BA066B0

--doesnt work until I drop and recreate that table type
DROP TYPE dbo.TestType_Old
GO

0 个答案:

没有答案