以编程方式为用户定义的数据类型 (UDDT) 生成 DDL 语句
Posted
技术标签:
【中文标题】以编程方式为用户定义的数据类型 (UDDT) 生成 DDL 语句【英文标题】:Programmatically generate DDL statement for User Defined Data Type (UDDT) 【发布时间】:2019-10-22 05:18:47 【问题描述】:我正在尝试为tSQLt 添加指向远程对象支持(PR) 的伪造同义词。
为了能够模拟/伪造在表定义中具有用户定义系统类型的表,我需要生成用户定义数据类型 (UDDT) DDL 语句。
我对 UDDT 没有太多经验,如果 UDDT 与 CREATE TYPE dbo.SomeType FROM INT
一样简单,我能想到的非常简单的场景,但我知道它可以更多复杂的。
所以,问题是是否有人已经有了一些可行的解决方案,最好是通过系统对象使用 T-SQL 实现。在最坏的情况下,SQLCLR 将是唯一的其他选择。
【问题讨论】:
我不明白你在问什么?我假设不是按照docs? 的常规创建 你可以参考这个:mssqltips.com/sqlservertip/1628/… 我已经更新了问题 您对使用 SQLCLR 感兴趣吗?还是 SMO? 有不同种类的用户定义类型:用户定义表类型(UDTT)、用户定义类型(UDT;通过 SQLCLR 实现的复杂类型)和用户定义数据类型(UDDT;主要是现有系统类型的同义词,但包括大小/精度和NULL
/NOT NULL
)。我更新了标题、问题和标签,以反映您真正询问的是 UDDT,而不是 UDT。
【参考方案1】:
有不同种类的用户定义类型:用户定义表类型(UDTT)、用户定义类型(UDT;通过 SQLCLR 实现的复杂类型)和用户定义数据类型(UDDT;主要是现有系统的同义词)类型,但包含大小/精度和 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';
。
【讨论】:
默认值和规则呢? @DmitrijKultasev 好的,添加了规则和默认值的信息。 非常不太可能使用任何一种,所以我需要重新关注我落后的东西......如果你需要它们,提供的信息(在示例代码下方)应该足够了得到他们。祝你好运! 你怎么知道它们已被弃用?我已经尝试谷歌并没有找到任何官方文档可以说明,无论如何,谢谢 @DmitrijKultasev 不客气。回复:已弃用的规则和默认值,为什么要看 Google?只需查看我为每个链接链接的文档即可。每个页面顶部都有一个横幅,上面写着:“重要此功能处于维护模式,可能会在 Microsoft SQL Server 的未来版本中删除。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序。”另请参阅:docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008/…以上是关于以编程方式为用户定义的数据类型 (UDDT) 生成 DDL 语句的主要内容,如果未能解决你的问题,请参考以下文章
C#编程(四十一)----------用户定义的数据类型转换