【问题标题】:Case Sensitive column names in Sql Azure DatabaseSql Azure 数据库中区分大小写的列名称
【发布时间】:2013-12-24 08:15:37
【问题描述】:

我一直在 Sql Server (SQL_Latin1_General_CP1_CS_AS) 中使用区分大小写的排序规则。我正在尝试迁移到 Sql Azure 数据库,但遇到了意外问题。看起来不可能有区分大小写的列名。这是真的吗?

我创建了我的数据库...

CREATE DATABASE MyDatabase
COLLATE SQL_Latin1_General_CP1_CS_AS

然后我创建了我的表...

CREATE TABLE [MyTable]
(
    [Name] NVarChar (4000) COLLATE SQL_Latin1_General_CP1_CS_AS NULL,
    [name] NVarChar (4000) COLLATE SQL_Latin1_General_CP1_CS_AS NULL                                                                                
)

我得到了错误: 每个表中的列名必须是唯一的。表“MyTable”中的列名“name”被指定了多次。

呃,灾难。这在 Sql Server 2012 中完美运行。但是在 Sql Azure 上我似乎无法实现。有谁知道为什么这在 Sql Azure 中不起作用?有谁知道我如何在 Sql Azure 中完成这项工作?谢谢。

【问题讨论】:

    标签: sql sql-server database azure


    【解决方案1】:

    我认为这是 Windows Azure SQL 中的一个错误!

    在线文档声明您可以在数据库、列或表达式级别覆盖排序规则。您不能在服务器级别执行此操作。

    http://msdn.microsoft.com/en-us/library/windowsazure/ee336245.aspx#sscs

    让我们从我们知道可行的方法开始,即本地安装 SQL Server 2012。

    -- Start at master
    Use master;
    Go
    
    -- Create a new database
    CREATE DATABASE Koopa
      COLLATE SQL_Latin1_General_CP1_CS_AS;
    
    -- Use the new database
    Use Koopa;
    Go
    
    -- Create a new table
    CREATE TABLE [MyTable]
    (
        [ColName1] NVarChar (4000) COLLATE SQL_Latin1_General_CP1_CS_AS NULL,
        [colname1] NVarChar (4000) COLLATE SQL_Latin1_General_CP1_CS_AS NULL                                                                                
    );
    

    如果我们尝试在 MASTER 数据库中运行 create table,则会收到您的错误。

    消息 2705,第 16 级,状态 3,第 2 行

    每个表中的列名必须是唯一的。表“MyTable”中的列名“colname1”被指定了多次。

    如果我们在 Koopa 数据库中运行 create table,它可以正常工作。见下图。那是因为 MASTER 是不区分大小写的 CI!

    我将使用 Azure SQL 数据库的 Web 界面,因为它有漂亮的颜色(它是网络)!

    让我们使用区分大小写排序规则创建一个新数据库。哇,我很兴奋,因为有一个选项可以选择我们的排序规则。

    现在我们有了一个新数据库,让我们检查一下设置!

    我仍然很高兴,因为我们看到为数据库列出了正确的排序规则。

    让我们直接登录到数据库服务器并运行一个简单的查询来创建表。

    我要先试试设计师!

    糟糕,它不起作用。

    让我们在查询窗口中尝试一个简单的 DDL 语句。

    现在我真的很失望。我们卖了一张货物清单,但 Azure SQL 没有交付。

    简而言之,文档说您不能在服务器级别设置排序规则。

    http://technet.microsoft.com/en-us/library/ms143726.aspx

    但是,来自 BOL 的这句话表明我们应该能够在数据库级别覆盖它。

    服务器级排序规则 默认服务器排序规则在 SQL Server 安装过程中设置,也成为系统数据库和所有用户数据库的默认排序规则。请注意,在 SQL Server 设置期间不能选择仅 Unicode 排序规则,因为它们不支持作为服务器级排序规则。

    简而言之,在接下来的 7 天里,我非常忙于 PASS 的几次演讲活动。我将不得不打开一份错误报告或查看是否已打开。

    好发现!!

    顺便说一句 - 您现在需要使用不同的列名。

    【讨论】:

      【解决方案2】:

      要解决您的问题,您需要添加 CATALOG_COLLATION。

      CREATE DATABASE MyDatabase COLLATE SQL_Latin1_General_CP1_CS_AS WITH CATALOG_COLLATION = DATABASE_DEFAULT 
      

      来源:What will happen with CATALOG_COLLATION and Case Sensitive vs Case Insensitive

      不幸的是,您似乎只能在其中放置两个值: SQL_Latin1_General_CP1_CI_AS 或 DATABASE_DEFAULT

      我有镜子问题。我想让模式对象(表名、列名等)成为 CI,数据库内部的数据成为 CS。 - 这在 Azure 中默认使用 CS COLLATE 例如。 SQL_Latin1_General_CP1_CS_AS 在数据库创建时设置。 但它不适用于本地 SQLEXPRESS 数据库,这是在本地测试应用程序的问题。当您创建数据库区分大小写的 CS 时,所有查询也开始区分大小写。这使我的休眠停止工作。 (对象不存在等)。

      为了解决这个问题,我需要使用 SQL_Latin1_General_CP1_CI_AS COLLATE 创建数据库,并为每一列分别定义 CS COLLATE:

      create table test (
       pk int PRIMARY KEY,
       data_cs varchar(123) COLLATE SQL_Latin1_General_CP1_CS_AS,
       CONSTRAINT [unique_data] UNIQUE NONCLUSTERED (data_cs)
      )
      
      insert into TEST values (1, 'ABC');
      insert into tEsT values (2, 'abc');
      
      select * from TEST where DATA_cs like 'A%'
      

      我猜 CATALOG_COLLATION 只能在 Azure SQL 中使用。

      【讨论】:

        【解决方案3】:

        在 SQL Server 中,有两个级别的排序规则:服务器级排序规则,它影响 DDL 事务(在这种情况下,例如表名和列名);和数据库级排序规则,这会影响数据库中包含的表的内容(即varchar 列值)。

        在 SQL Server 中,数据库级别的排序规则是在服务器设置期间指定的。您可能在安装 SQL Server 时将其设置为自定义。因为您无法控制 SQL Azure 的服务器级配置,这意味着您必须符合 Microsoft 的排序规则,在这种情况下,不使用区分大小写的 DDL 标识符,这无论如何都是一种好的做法。

        本 QA 对此进行了详细说明:Does sqlserver collation mean column names must be correct case? And how to deal with that

        【讨论】:

        • 我的 Sql Server 2012 实例的排序规则设置为 SQL_Latin1_General_CP1_CI_AS (所以我的服务器仍然处于不区分大小写模式,默认值,通过运行 SELECT SERVERPROPERTY('Collat​​ion') 确认)所以服务器排序规则属性不是控制 Sql 2012 中的 DDL 事务,因为我的大小写敏感性在那里工作得很好。我假设并且仍然假设 DDL 区分大小写是由数据库的排序规则属性控制的,而不是服务器的。为什么这在 Sql Azure 中会有所不同?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-13
        • 1970-01-01
        • 1970-01-01
        • 2014-01-19
        • 2011-01-13
        • 2016-11-24
        • 2016-01-17
        相关资源
        最近更新 更多