1

考虑以下 T-SQL 语句:

create type mytype from decimal(8,3)
go

create function f (@x int) 
returns mytype
with schemabinding
as 
begin
    return @x * @x
end

当我使用 SQL Server 2017 (v14.xx) 尝试此操作时,我收到此错误:

消息 2792,级别 16,状态 1,过程 f,第 6 行(批处理开始第 2 行)
无法在架构绑定对象或约束表达式中指定 SQL CLR 类型。

的文档create type说明它

创建别名数据类型或用户定义类型 [in a database]。[...] 用户定义类型是通过 [CLR] 中的程序集类实现的。

这种听起来像是“用户定义的类型”和“CLR 类型”(如错误消息中所命名)可能只是同一事物的两个名称,但“别名数据类型”是(或可以是)别的东西。

我不想要任何 CLR 支持,我想做的只是给类型一个名称,以便它可以在多个函数定义和调用这些函数的任何代码中一致地使用。我想要模式绑定,因为它在使用这些函数的查询中产生了显着的性能改进。

如果我查找它已设置mytype为1,但设置为 0。sys.typesis_user_definedis_assembly_type

那么,“用户定义类型”和“CLR 类型”是同一事物的两个名称吗?“别名数据类型”有什么不同吗?它们似乎在create type. 当它真的意味着任何用户定义的类型时,这个错误消息是否只是通过引用“CLR 类型”而令人困惑?

我可以做我想做的事还是必须放弃别名类型声明或模式绑定?

4

1 回答 1

1

问题来自自定义类型的历史:

  • 一开始,您使用的别名类型称为 a user-defined data type
  • 当 CLR 出现时,他们调用了您可以在那里创建的自定义类型user-defined data types,并重命名了旧的类型alias types现在它被称为 auser-defined data type alias可以说更加令人困惑)。

并非所有编写文档和错误消息的人都收到了备忘录,因此您可能会看到类似这样的几种情况,它们可以互换使用。由于向后兼容性,这些在很大程度上无法修复(更改错误消息中的文本可能会破坏解析消息的代码)。这不是一个好的借口,但它是一个始终如一的借口。

至于你的选择

您可以删除模式绑定或删除别名类型。我会做后者,只是远离别名类型,句号。您可能认为它们为您节省了一些打字时间,但代价是痛苦。除了模式绑定,等到您尝试将其更改为 decimal(10,3)。与使用别名类型相比,使用模式绑定肯定有更多(和更切实)的好处。

老实说,我不认为这种行为是预期的。我想不出你不能模式绑定别名类型的原因,因为无论如何这本质上是相反的行为。但是你必须与微软一起接受它才能改变它。

于 2021-09-28T15:14:49.050 回答