使用绑定规则和默认值的SQL Server用户定义类型被弃用,需要替换。

8
我们有一个名为YesNo的用户自定义数据类型,它是char(1)的别名。该类型有一个绑定规则(必须为Y或N)和一个默认值(N)。
这样做的目的是,当任何开发团队创建一个新的YesNo类型字段时,规则和默认值会自动绑定到新列上。
规则和默认值已被弃用,并且在未来版本的SQL Server中将不再提供,是否有其他方法实现相同的功能?
我应该补充说明的是,我知道可以使用CHECK和DEFAULT约束来复制绑定规则和默认对象的功能,但这些约束需要应用于每个使用该类型的地方,而不是通过使用具有绑定规则和默认值的UDT来获得“免费”的功能。
此帖子与支持现有应用程序的数据库相关,而不是新开发,因此我们对UDT的使用不够理想。
我怀疑这个问题的答案是“没有”,然而通常当一些特性被弃用时,通常会有替代语法可用作为替换,所以我想提出这个问题,以防有人知道替代方案。

我认为您误读了文章。CREATE RULE 和 CREATE DEFAULT 已经被弃用,现在应该在 CREATE TABLE 或 ALTER TABLE 语句中指定 DEFAULTS 和 CHECK rules。 - Bill
这是我总是声明我的地方。 - Mitch Wheat
编辑以反映正确的弃用时间表。 - Adam Jones
4
@Bill,我了解他们希望我使用的内容,这也是我发帖的目的。使用约束条件需要开发人员每次在使用UDT时都要将约束条件添加到每个表中,而使用绑定规则和默认值的UDT,则可以在每次使用该类型时免费获得它,这消除了我们开发过程中可能存在的潜在人为错误点。 - Adam Jones
3个回答

1

默认和检查约束...

CREATE TABLE foo (
   col1 int...
   YesNo char(1) NOT NULL DEFAULT ('N')
                   CONSTRAINT CK_foo_YesNo CHECK (YesNo IN 'Y', 'N'))
   col2 ...
   )

就我个人而言,我不倾向于使用UDT(我记得上一次使用是SQL Server 6.5),因为如果有任何更改,就没有ALTER TYPE可用...

至于弃用...

在SQL Server 2005的CREATE RULE中首次提到。所以我们被告知了6年和3个版本之前

对于SQL Server 2000...

"规则是向后兼容功能,执行与检查约束执行的一些相同的功能。 使用ALTER或CREATE TABLE的CHECK关键字创建的CHECK约束是首选的标准方式..."

对于CREATE DEFAULT也是如此,是对象而不是约束

这是11年前的事了


我也很想摆脱UDT,但在这种情况下它们是有用的,并且是这个特定数据库的一部分,已经存在了很长时间。我知道我可以更新每个类型的使用方式,以具有约束和默认值,但这意味着每次使用该类型时都要应用约束和默认值,我想问的是是否有一种方法可以实现我们目前拥有的东西,即具有默认值并且只能接受某些值的类型,而不需要在每个单独使用中添加代码。 - Adam Jones
@Adam Jones:可能不是你想要的,但你有没有考虑使用非空位并在客户端更改为Y或N?这样,它就是具有仅限2个值的“内置”约束的本地数据类型。同时,您可以使用计算列来提供读取的Y或N:您只需要将写入更改为位即可。 - gbn
谢谢您的建议,这是未来的可能性。在某个时候,我想剥离所有的UDT,并将YesNo更改为非空位,这将列入待办事项清单。问题实际上只是出于好奇。我已经寻找了一个“插拔式”替代我们当前功能的解决方案,但没有找到任何东西。我在这里提出这个问题,以防我错过了什么。不幸的是,我怀疑我的问题的简短答案是“否”。 - Adam Jones

0

“规则和默认值已被弃用,并且将不会在下一个版本的SQL Server中提供”

1)据我所知,这不是真的。你不能突然打破99.9%的TSQL!

2)即使它是真的(我坚信它不是),弃用并不意味着在下一个版本中删除,只是表示该功能不应在新代码中使用。

您是否有任何官方链接来证实此类公告?

用户@gbn似乎认为我正在捍卫弃用的结构的使用。我没有。


CREATE RULE是针对SQL Server 2005的功能。你只有6年和3个版本。对于SQL Server 2000来说,“规则”是一种向后兼容的功能,执行与检查约束相同的某些功能。使用ALTER或CREATE TABLE的CHECK关键字创建的CHECK约束是首选的标准方式...这已经11年了... - gbn
在你的回答中解决以下问题:“你有任何官方链接可以证明这样的声明吗?”和“据我所知,那不是真的。你不能突然打破99.9%的TSQL!”。你已经有足够的时间来进行调整了... - gbn
@gbn:我不知道你在说什么。我所指的是任何“已弃用”的东西。我个人不使用规则。我会内联声明我的约束条件(正如我在这个问题的其他地方所说)。 - Mitch Wheat
@gbn:这不是我想说的:我永远不会建议任何人使用已弃用的结构。就这样。 - Mitch Wheat
@Mitch Wheat:你说“据我所知,那不是真的。”对于弃用,然后要求一个链接。你的评论表明你确实知道。然后你指责我在你实际发布的答案中挑毛病。再次问一下:你的回答有什么意义? 在回复此评论之前,请阅读你自己的答案。 - gbn
显示剩余6条评论

-1

Xquery 对于处理这样简单的任务来说有点晦涩难懂。我通常会用它来处理更复杂的数据类型,但它(我认为)确实回答了您关于替换的问题。以下是我如何实现一个参数作为已输入的 XML,并且必须为 true 或 false。您可以将其扩展为是/否或狗狗/猫咪等任何您想要的内容。

if schema_id(N'chamomile') is null
  execute (N'create schema chamomile');
go
set nocount on;
go
/*
  All content is licensed as [chamomile] (http://www.katherinelightsey.com/#!license/cjlz) and 
    copyright Katherine Elizabeth Lightsey, 1959-2014 (aka; my life), all rights reserved,
    and as open source under the GNU Affero GPL (http://www.gnu.org/licenses/agpl-3.0.html).
  ---------------------------------------------
*/
if exists
   (select xml_collection_id
    from   sys.xml_schema_collections as true_false
    where  true_false.name = 'true_false'
           and true_false.schema_id = schema_id(N'chamomile'))
  drop xml schema collection [chamomile].[true_false];
go
/*
  --
  -- License
  ----------------------------------------------------------------------
  Katherine E. Lightsey
  http://www.katherinelightsey.com

  All content is copyright Katherine Elizabeth Lightsey, 1959-2014 (aka; my life), all rights reserved, 
  licensed as [chamomile] (http://www.katherinelightsey.com/#!license/cjlz) and copyright Katherine Elizabeth Lightsey, 1959-2014 (aka; my life), all rights reserved, 
    and as open source under the GNU Affero GPL (http://www.gnu.org/licenses/agpl-3.0.html).

  --
  -- to view documentation
  -----------------------------------------------------------------------------------------------
  select objtype
       , objname
       , name
       , value
  from   fn_listextendedproperty (null
                  , 'schema'
                  , 'chamomile'
                  , 'xml schema collection'
                  , 'true_false'
                  , default
                  , default);
*/
create xml schema collection [chamomile].[true_false] as N'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:chamomile="http://www.katherinelightsey.com/" targetNamespace="http://www.katherinelightsey.com/">

    <xsd:element name="true_false" type="chamomile:true_false_type" />

    <xsd:complexType name="true_false_type">
      <xsd:complexContent>
        <xsd:restriction base="xsd:anyType">
          <xsd:attribute name="true_false" type="chamomile:pass_fail_enumeration" default="false" />
        </xsd:restriction>
      </xsd:complexContent>
    </xsd:complexType>

  <xsd:simpleType name="pass_fail_enumeration">
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="true" />
      <xsd:enumeration value="false" />
    </xsd:restriction>
  </xsd:simpleType>

</xsd:schema>';
go
declare @true_false xml([chamomile].[true_false]) = N'<chamomile:true_false xmlns:chamomile="http://www.katherinelightsey.com/" true_false="true" />';
if (select @true_false.value(N'(/*/@true_false)[1]', N'[sysname]'))
   = N'true'
  select N'true';
go
declare @true_false xml([chamomile].[true_false]) = N'<chamomile:true_false xmlns:chamomile="http://www.katherinelightsey.com/" true_false="false" />';
go
declare @true_false xml([chamomile].[true_false]) = N'<chamomile:true_false xmlns:chamomile="http://www.katherinelightsey.com/" true_false="not_valid" />';
go  

我认为如果提供一个带有类型化的xml列和您的true_false规则的CREATE TABLE示例,这个答案将会得到极大的改进。当然,对于OP的用例来说,使用xml是相当过度的,虽然SQL Server对于类型化的xml列和参数支持XML Schema验证,提供了与旧的RULE对象类似的用户体验,但没有其他真正的优势... - Dai
此外,在 SO 上发布 AGPL 代码违反了 SO 的用户协议[规定我们的贡献是 CC-BY-SA,而不是 AGPL]。(参见https://stackoverflow.com/help/licensing) - Dai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接