7

我使用的数据库有 French_CI_AS 排序规则(CI 应该代表不区分大小写),但无论如何都是区分大小写的。我试图理解为什么。

我断言这一点的原因是具有“给定”案例设置的批量插入失败,但它们通过另一个“给定”案例设置成功。

例如:

  • INSERT INTO SomeTable([GIVEN],[COLNAME]) VALUES ("value1", "value2")失败,但是
  • INSERT INTO SomeTable([Given],[ColName]) VALUES ("value1", "value2")作品。

编辑 刚刚看到这个:

http://msdn.microsoft.com/en-us/library/ms190920.aspx

所以这意味着应该可以在不清空所有数据并重新创建相关表的情况下更改列的排序规则?

4

3 回答 3

8

鉴于这条关键信息(即在对问题的评论中,而不是实际问题中):

事实上,我使用 Microsoft .Net 的批量插入方法,所以我真的不知道它发送到数据库服务器的确切查询。

即使在不区分大小写的数据库中,列名被视为区分大小写也是有道理的,因为这就是SqlBulkCopy类的工作方式。请参阅SqlBulkCopy 中的列映射区分大小写

补充说明

  1. 在询问错误时,请始终在问题中包含实际完整的错误消息。简单地说有一个错误会导致大量的猜测和疯狂的追逐,进而导致离题的答案。
  2. 提出问题时,请不要改变您正在处理的情况。例如,问题状态(强调):

    具有“给定”案例设置的批量插入失败,但它们通过另一个“给定”案例设置成功。

    然而,示例语句是单INSERTs。此外,对该问题的评论指出:

    事实上,我使用 Microsoft .Net 的批量插入方法,所以我真的不知道它发送到数据库服务器的确切查询。

    使用 .NET 与SqlBulkCopy使用BULK INSERTor完全不同INSERT,这会使当前问题具有误导性,从而难以(甚至不可能)正确回答。这条新信息也引发了更多问题,因为在使用 时SqlBulkCopy,您无需编写任何INSERT语句:您只需编写一条SELECT语句并指定目标表的名称。如果您完全为目标表指定列名,则它位于可选列映射中。这就是问题所在吗?

  3. 关于问题的“编辑”部分:

    不,即使您没有使用SqlBulkCopy. 列的排序规则决定了存储在列中的数据的行为方式,而不是列名(即表的元数据)的行为方式。数据库本身的排序规则决定了数据库级对象元数据的行为方式。在这种情况下,您声称数据库正在使用不区分大小写的排序规则(正确,_CI_排序规则名称的一部分确实意味着“区分大小写”)。

  4. 关于 Jonathan Leffler 就该问题所作的以下陈述:

    这进入了分隔标识符(通常区分大小写)和排序规则(这个不区分大小写)之间交互的一个非常微妙的领域。

    不,分隔标识符通常不区分大小写。分隔标识符的敏感性(大小写、重音、假名类型、宽度和在 SQL Server 2017 变体选择器中的开头)与同一级别的非分隔标识符相同。“同一级别”是指实例级别的名称(数据库、登录名等)由实例级别的排序规则控制,而数据库级别的名称(架构、对象--表、视图、函数、存储过程等--、用户等)由数据库级排序规则控制。并且这两个级别可以有不同的排序规则。

    您需要研究数据库中的 SQL 列名在分隔时是否区分大小写。它还可能取决于 CREATE TABLE 语句的编写方式(名称是否在其中分隔?)。通常,SQL 对列名和表名不区分大小写;你可以写INSERT INTO SoMeTaBlE(GiVeN, cOlNaMe) VALUES("v1", "v2"),如果名字从来没有分隔,那就没问题了。

    在创建表时列名是否被分隔并不重要,至少在如何处理它们的分辨率方面无关紧要。列名是数据库级元数据,由数据库的默认排序规则控制。每个数据库中的所有数据库级元数据都是相同的。您不能让某些列名区分大小写而其他列名不区分大小写。

    此外,表名和列名也没有什么特别之处。它们是数据库级别的元数据,就像用户名、模式名称、索引名称等一样。所有这些元数据都由数据库的默认排序规则控制。

    元数据(实例级别和数据库级别)仅“通常”不区分大小写,因为安装期间建议的默认排序规则是不区分大小写的排序规则。

    'delimited identifier' 是列名、表名或用双引号括起来的类似内容,例如 CREATE TABLE "table"(...)

    更准确地说,定界标识符是包含在所讨论的 DBMS 定义为其定界符的任何字符中的标识符。哪些特定字符用于分隔符在不同的 DBMS 之间有所不同。

    在 SQL Server 中,分隔标识符用方括号括起来:[GIVEN]

    虽然方括号始终用作标识符的分隔符,但如果您将会话级属性QUOTED_IDENTIFIER设置为ON(最好始终这样做),则可以使用双引号作为分隔符。

    SQL 有一些晦涩难懂的部分(分隔标识符处理就是其中之一)

    好吧,分隔标识符实际上非常简单。定界标识符的全部意义在于有效地忽略常规(即非定界)标识符的规则。但是,就常规标识符而言,是的,这些规则相当神秘(主要是由于官方文档不完整且不正确)。因此,为了揭开 SQL Server 中标识符实际工作原理的神秘面纱,我进行了大量研究并在此处发布了结果(其中包括研究本身的链接):

    完整的 T-SQL 标识符规则列表

有关排序规则 / 编码 / Unicode / ASCII 的更多信息,尤其是与 Microsoft SQL Server 相关的信息,请访问:

校对信息

于 2017-05-20T13:04:11.207 回答
1

列名区分大小写的事实意味着 MASTER 数据库是使用区分大小写的排序规则创建的。

如果我只是让我对此进行调查,有人进入

Latin1_C S _A I 而不是 Latin1_C I _A S

设置 SQL 服务器时。

于 2017-03-20T09:36:22.797 回答
0

检查表定义中列的排序规则,以及 tempdb 数据库的排序规则(即服务器排序规则)。它们可能与您的数据库排序规则不同。

于 2012-05-03T14:25:27.410 回答