以编程方式为用户定义数据类型 (UDDT) 生成 DDL 语句

Programmatically generate DDL statement for User Defined Data Type (UDDT)

我正在尝试添加指向远程对象的伪造同义词支持(PR) for tSQLt

为了使在 table 定义中具有用户定义系统类型的 mock/fake table 成为可能,我需要生成用户定义数据类型 (UDDT) DDL 语句.

我对 UDDT 没有太多经验,如果 UDDT 就像 CREATE TYPE dbo.SomeType FROM INT 一样简单,我能想到的非常简单的场景,但我知道它可能要复杂得多。

所以,问题是是否有人已经有了一些可行的解决方案,最好是通过系统对象使用 T-SQL 实现。在最坏的情况下,SQLCLR 将是唯一的选择。

有不同种类的用户定义类型:用户定义 Table 类型 (UDTT)、用户定义类型(UDT;通过 SQLCLR 实现的复杂类型)和用户定义数据类型 (UDDT ; 主要是现有系统类型的同义词,但包括 size/precision 和 NULL / NOT NULL)。

您不必担心 UDTT,因为它们不能是表中的列。

您可能无法处理 UDT,至少现在不能,因为这会增加很多复杂性,因为您还需要复制程序集。

有一个主要的系统目录视图:sys.types。以下内容应该可以满足您的大部分需求(如果不是全部的话)。 collation_name 似乎无法使用,无论是通过测试简单的 CREATE TYPE 作为测试,还是通过文档。

SELECT N'CREATE TYPE ' + QUOTENAME(sch.[name])
         + N'.' + QUOTENAME(typ.[name])
         + N' FROM ' + styp.[name]
         + CASE
             WHEN typ.[system_type_id] IN
                       (41, 42, 43, 106, 108, 165, 167, 173, 175, 231, 239)
               THEN N'('
                    + CASE
                        WHEN typ.[max_length] = -1 -- for: VARCHAR, NVARCHAR, VARBINARY
                          THEN N'MAX'
                        WHEN typ.[system_type_id] IN (165, 167, 173, 175)
                          -- VARBINARY, VARCHAR, BINARY, CHAR
                          THEN CONVERT(NVARCHAR(5), typ.[max_length])
                        WHEN typ.[system_type_id] IN (231, 239) -- NVARCHAR, NCHAR
                          THEN CONVERT(NVARCHAR(5), (typ.[max_length] / 2))
                        WHEN typ.[system_type_id] IN (41, 42, 43)
                          -- TIME, DATETIME2, DATETIMEOFFSET
                          THEN CONVERT(NVARCHAR(5), typ.[scale])
                        WHEN typ.[system_type_id] IN (106, 108) -- DECIMAL, NUMERIC
                          THEN CONVERT(NVARCHAR(5), typ.[precision]) 
                               + N', ' + CONVERT(NVARCHAR(5), typ.[scale])
                        END            
                    + N')'
             ELSE N''
           END
         + CASE typ.[is_nullable] WHEN 1 THEN N' NULL' ELSE ' NOT NULL' END
         + N';'
FROM   sys.types typ
INNER JOIN sys.schemas sch
        ON sch.[schema_id] = typ.[schema_id]
INNER JOIN sys.types styp
        ON styp.[user_type_id] = typ.[system_type_id]
WHERE  typ.[is_user_defined] = 1
AND    typ.[is_assembly_type] = 0
AND    typ.[is_table_type] = 0;

规则

!!这些已被弃用很长时间,不应使用!!

Documentation 对于 CREATE RULE

规则可在以下位置找到:sys.sql_modules(其中包括 [definition] 字段中的 CREATE 语句)

您将需要单独循环 sys.types,并且对于任何用户创建的类型 rule_object_id <> 0,执行 EXEC sp_bindrule N'@rulename', N'@objectname';.

默认值

!!这些已被弃用很长时间,不应使用!!

Documentation 对于 CREATE DEFAULT

可以在以下位置找到默认值:sys.sql_modules(其中包括 [definition] 字段中的 CREATE 语句)

您将需要单独循环 sys.types,并且对于 default_object_id <> 0 中的任何用户创建的类型,执行 EXEC sp_bindefault N'@defaultname', N'@objectname';.