有两个原因促使我提出这个问题:
tSQLt当存在具有非默认排序规则的列时,
T-SQL 测试框架 tSQLt 将其视为“高严重性”问题。测试的作者陈述如下:
我并不是建议每个字符串列都应该有一个与数据库的默认排序规则相匹配的排序规则。相反,我建议当它不同时,应该有一个很好的理由。
然而,如前所述,失败测试的严重性被认为是高的。
Octopus Deploy
在配置 Octopus Deploy Server 时,在 OctopusServer-instance 初始化期间设置失败并出现致命错误。与错误消息相关的文章没有解释为什么这是一个要求,而只是说明它将是未来部署的要求,从并包括 Octopus 版本 3.8。
作为旁注,RedGate 的 CI 工具包DLM 自动化套件支持具有不同排序规则的部署,而不会引起任何抱怨。
将所有列排序规则保留为数据库默认值的建议对我来说更像是指导方针或最佳实践。为什么有些人认为这是一个如此严重的错误?
你在这里是完全正确的。
出于同样的原因,你会经常听到/读到“你永远不应该使用:”
GOTO
陈述WITH (NOLOCK)
某些功能/选项/技术比其他功能/选项/技术更复杂,并且通常需要用户更多的知识,因为使用它时遇到麻烦的机会远大于没有任何问题的机会。因此,针对普通人群制定针对此类事情的通用规则会更容易。事实上,在工作中写“编码标准”时,我总是有一条规则,永远不要使用 CURSOR,但我自己使用它们,因为我知道“何时”使用它们以及“如何”有效地使用它们。但是不应该期望那些只是偶尔写查询的人知道这一点。这也类似于“除非您绝对知道自己在做什么,否则不要编辑注册表”,或者我们作为父母为我们(非常年幼的)孩子制定的规则,我们需要告诉他们不要仅仅因为他们是无法跨越何时可以做某件事或如何去做这件事的复杂性。
在排序规则的情况下,这是一个非常复杂且令人困惑的主题,您可能会遇到硬错误(这些是一个问题,但不是问题,因为它们很明显,因此很容易修复)和“奇怪”难以解释为什么事情会以现在的方式运行的行为(为什么某些项目被过滤或未过滤,超出预期,或者为什么排序的行为超出预期)。可悲的是,似乎有相当多的错误信息漂浮在周围,加剧了大众的混乱。我实际上正在开展一个项目,以极大地增加排序规则和编码等方面的一般知识,并希望消除错误信息和神话,但尚未准备好发布它(完成后我将通过链接更新它)。
对于排序规则,您需要使用对业务案例最有意义的内容。不在表或数据库中混合排序规则的概念是默认方法,但如果您查看用于系统目录视图的各个列的排序规则,您会注意到正在使用各种排序规则。因此,我同意问题中的主要引述,即如果排序规则会有所不同,那应该是有意的,但它本质上没有任何问题。
关于这个问题(强调补充):
我检查了链接的文档页面,它确实解释了为什么它是一个要求。我已从以下文档中复制了相关信息:
他们说他们的代码,在 Octopus 数据库中,在字符串列之间有 JOIN,并且可能会在未来的升级中引入新代码,在新的字符串列上有额外的 JOIN。新列(通过
CREATE TABLE
或ALTER TABLE ... ADD
)将被分配数据库的默认排序规则,如果COLLATE
没有为新的字符串列指定关键字。并且没有相同 Collation 的字符串列之间的 JOIN 会产生一个 Collation mismatch 错误。他们似乎还允许用户选择自己的排序规则(可能是为了适应不同的语言环境),因为他们在顶部说唯一的要求是排序规则不区分大小写。而且由于他们的代码所在的数据库的排序规则不能保证总是相同的,他们不能使用COLLATE
关键字来强制所有新的字符串列使用相同的排序规则(嗯,他们在技术上可以,但这需要动态SQL 在生成更新脚本时不容易处理)。如果他们能够使用COLLATE
关键字,那么他们可以让数据库的默认排序规则与字符串列不同。这将避免硬的“排序规则不匹配”错误,但仍会保留涉及这些字符串列之一和字符串文字或变量的比较操作的可能性,从而导致“奇怪”行为,因为它将使用列的排序规则而不是数据库的整理。当然,这很可能是预期的行为。但由于这是一个第 3 方应用程序,行为应该是他们的意图,而不是 a) 用户想要(或不反对)和 b) 用户认为错误的 50 / 50 机会(然后将供应商的支持时间浪费在追逐和/或关于他们的软件如何存在错误的博客上)。一句话简介:COLLATION 定义了排序和比较。
因此,排序规则决定了 SQL Server 用于比较和排序字符数据的规则。这些规则是语言/区域感知的,也可能对大小写、重音、假名和宽度敏感。排序规则后缀标识字典规则的(in)敏感性:_CS(区分大小写)、_CI(不区分大小写)、_AS(区分重音)、_AI(不区分重音)和_KS(区分假名)。由后缀 _BIN(二进制)和 _BIN2(二进制代码点)标识的二进制排序规则在所有方面都是敏感的。
不同的排序规则肯定需要变通方法来避免“无法解决排序规则冲突”错误,并且由于已知的不可解析表达式可能会降低性能。处理不同的排序规则可能是一场噩梦(一直在那里),所以这就是为什么建议选择一个并坚持下去的原因。
更多参考:
与许多事情一样,在以前的 SQL 版本中,它可能会导致相当严重的问题。请参阅 SQL7/2000 中的这篇文章
SqlServerCentral 排序规则
它现在更加强大,并且在某些情况下它在更现代的系统中是合理的,但是仍然有一些相当有趣的警告来改变它。
这是另一个关于更现代版本的有用系列。丹·古兹曼(Dan Guzman),我相信他经常在这里发帖,所以他可能很快就会发帖:)
SQL 排序规则地狱
简而言之,兼容性、标准化和潜在的性能损失是不使用混合排序规则的主要原因。
如果数据是 char(8 位文本)而不是 nchar(16 位),则在排序规则之间传输数据可以更改数据。
我相信从这个页面https://the.agilesql.club/blogs/Blogs/Ed-Elliott/What-collation- variables-take-on-inT-SQL ,当一个变量被分配了一个表中的文本时,它是隐式翻译为/视为当前数据库的排序规则。但是当您移动到不同的数据库时,变量中的文本会发生什么变化?这些字节是否会再次(如果需要)转换为新的排序规则?
我采用了一个整理技巧来删除“拉丁”字母重音并只留下 ASCII 文本,这是我需要的,因为我们的第三方软件在重音上令人窒息 - 我将文本放入仅包含 ASCII 和现代希腊字母表的排序规则中;
Collate SQL_Latin1_General_CP1253_CI_AI
. “Slán”重读罗马字母!;-)但如果我想保留它们,那就是个坏消息!