【问题标题】:Is of a type that is invalid for use as a key column in an index?是否属于在索引中用作键列无效的类型?
【发布时间】:2015-05-18 08:43:48
【问题描述】:

我想创建一个名为 tbl_Ticket_Mail_Address 的表。创建表时显示错误。

表:

CREATE TABLE [dbo].[tbl_Ticket_Mail_Address] (
    [Id]           INT            IDENTITY (1, 1) NOT NULL,
    [Designation]  NVARCHAR (MAX) NULL,
    [Emp_ID]       NVARCHAR (MAX) NOT NULL,
    [Emp_Name]     NVARCHAR (MAX) NULL,
    [Mobile]       NVARCHAR (MAX) NULL,
    [Emp_Email]    NVARCHAR (MAX) NULL,
    [Category]     NVARCHAR (MAX) NULL,
    [Created_By]   NVARCHAR (MAX) NULL,
    [Created_Date] DATE           NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [uc_tbl_Ticket_Mail_Address] UNIQUE NONCLUSTERED ([Emp_ID] ASC, [Category] ASC)
);

58,1): SQL72014: .Net SqlClient 数据提供者: Msg 1919, Level 16, State 1, Line 1 表 'tbl_Ticket_Mail_Address' 中的列 'Emp_ID' 的类型不能用作关键列一个索引。 (58,0): SQL72045: 脚本执行错误。执行的脚本:

CREATE TABLE [dbo].[tbl_Ticket_Mail_Address] (
    [Id]           INT            IDENTITY (1, 1) NOT NULL,
    [Designation]  NVARCHAR (MAX) NULL,
    [Emp_ID]       NVARCHAR (MAX) NOT NULL,
    [Emp_Name]     NVARCHAR (MAX) NULL,
    [Mobile]       NVARCHAR (MAX) NULL,
    [Emp_Email]    NVARCHAR (MAX) NULL,
    [Category]     NVARCHAR (MAX) NULL,
    [Created_By]   NVARCHAR (MAX) NULL,
    [Created_Date] DATE           NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [uc_tbl_Ticket_Mail_Address] UNIQUE NONCLUSTERED ([Emp_ID] ASC, [Category] ASC)
);

(58,1): SQL72014: .Net SqlClient 数据提供者: Msg 1750, Level 16, State 0, Line 1 无法创建约束或索引。请参阅以前的错误。 (58,0): SQL72045: 脚本执行错误。执行的脚本: 执行批处理时出错。

【问题讨论】:

  • 你真的希望人们将莎士比亚的全集插入到例如Mobile?为您的列选择合理的数据长度,而不是一刀切地选择nvarchar(max),假设Emp_ID 下降到合理的大小,问题应该会消失。
  • @Damien_The_Unbeliever:谢谢。 ...
  • ID 列通常是数字。为什么Emp_ID 使用 nvarchar?

标签: sql-server


【解决方案1】:

SQL Server 不允许您使用nvarchar(max) 列创建唯一索引。正如 D_T_U 评论的那样,选择较小的尺寸,例如nvarchar(100) 并且您将能够创建索引。

当然,列大小需要符合您的要求,因此 100 只是一个示例。

额外信息:创建索引时,请记住组合索引值的大小不得超过 900 字节。每个nvarchar 字符将使用2 个字节,因此您最多可以拥有nvarchar(450) 的组合大小。例如,在您的情况下,您可以拥有

[Emp_ID] NVARCHAR (50) NOT NULL,
[Category] NVARCHAR (400) 

只要任何给定行上的数据不超过 900 字节,就可以为 nvarchar 列声明更大的大小,但这是危险的。例如,如果您将两列都声明为nvarchar(300),您将收到以下消息:

警告!最大密钥长度为 900 字节。指数 'uc_tbl_Ticket_Mail_Address' 的最大长度为 1200 字节。为了 一些大值的组合,插入/更新操作将 失败。

【讨论】:

    【解决方案2】:

    查看 MSDN 中的CREATE INDEX 语句。

    大对象 (LOB) 数据类型的列 ntext、text、 varchar(max)、nvarchar(max)、varbinary(max)、xml 或 image 不能 指定为索引的键列。

    要解决问题本身,请参考@Damien_The_Unbeliever 的评论。

    【讨论】:

      【解决方案3】:

      如果您的索引列已定义为 SPARSE,也会发生此错误。

      [hash] VARBINARY(32) SPARSE NULL -- Fail
      [hash] VARBINARY(32) NULL        -- Success
      

      (597,1):SQL72014:.Net SqlClient 数据提供者:消息 1919,级别 16, 状态 2,第 1 行表 'Document_JSON' 中的列 'hash' 属于一种类型 不能用作索引中的键列。

      (597,0): SQL72045: 脚本执行错误。

      【讨论】:

        猜你喜欢
        • 2011-02-21
        • 1970-01-01
        • 1970-01-01
        • 2012-10-19
        • 2013-04-03
        • 1970-01-01
        • 1970-01-01
        • 2018-04-01
        相关资源
        最近更新 更多