【问题标题】:How to add an index or primary key to a user-defined table type in SQL Server?如何在 SQL Server 中为用户定义的表类型添加索引或主键?
【发布时间】:2010-12-15 14:39:31
【问题描述】:

我有这个用户定义的类型,我想添加一个主键或索引:

IF NOT EXISTS (
  SELECT * 
  FROM sys.types st 
  JOIN sys.schemas ss 
    ON st.schema_id = ss.schema_id 
  WHERE st.name = N'DistCritGroupData' 
    AND ss.name = N'dbo')
BEGIN

  CREATE TYPE [dbo].[DistCritGroupData] AS TABLE
  (
    [DistCritTypeId] [int] NOT NULL,
    [ItemAction] [int] NOT NULL,        
    [ObjectId] [int] NOT NULL,
    [OperatorType] [int] NOT NULL     
  );

END;
GO  

我基本上想添加主键或聚集索引。我试过这个,但我收到错误“找不到对象“dbo.DistCritGroupData”,因为它不存在或您没有权限。

  CREATE TYPE [dbo].[DistCritGroupData] AS TABLE
  (
    [DistCritTypeId] [int] NOT NULL,
    [ItemAction] [int] NOT NULL,        
    [ObjectId] [int] NOT NULL,
    [OperatorType] [int] NOT NULL,
    CONSTRAINT [DistCritGroupData0] PRIMARY KEY CLUSTERED 
    (
       [DistCritTypeId] ASC
    )        
  );

我在对象资源管理器中看到我的用户定义表类型有“列”、“键”、“约束”和“索引”部分。问题是,如何添加键或索引?

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    为什么不这样?

    CREATE TYPE [dbo].[DistCritGroupData] AS TABLE
      (
        [DistCritTypeId] [int] NOT NULL PRIMARY KEY CLUSTERED,
        [ItemAction] [int] NOT NULL,        
        [ObjectId] [int] NOT NULL,
        [OperatorType] [int] NOT NULL     
      );
    

    CREATE TYPE [dbo].[DistCritGroupData] AS TABLE
      (
        [DistCritTypeId] [int] NOT NULL,
        [ItemAction] [int] NOT NULL,        
        [ObjectId] [int] NOT NULL,
        [OperatorType] [int] NOT NULL,
        PRIMARY KEY CLUSTERED ([DistCritTypeId] ASC)        
      );
    

    CREATE TYPE 不允许命名约束。像表变量一样。

    【讨论】:

      【解决方案2】:

      @bernd_K@gbn 的答案在单列 PK 时有效。对于多列,它将是:

      CREATE TYPE [dbo].[DistCritGroupData] AS TABLE
        (
          [DistCritTypeId] [int] NOT NULL,
          [ItemAction] [int] NOT NULL,        
          [ObjectId] [int] NOT NULL,
          [OperatorType] [int] NOT NULL,
          PRIMARY KEY (ColumnA,ColumnB)
        );
      

      简而言之,您可以拥有 PK 和 UNIQUE table constraints,但您不能命名它们。这种做法是有道理的,因为您将创建多个相同类型的对象,而您唯一需要处理这些约束的时候就是更改整个表类型。

      您也不能定义索引,因为它们主要是物理存储的产物。

      【讨论】:

        【解决方案3】:

        值得注意的是,您现在可以使用新的内联索引语法在 SQL 2014 的表类型中添加某些索引。例如:

          CREATE TYPE [dbo].[DistCritGroupData] AS TABLE
          (
            [DistCritTypeId] [int] NOT NULL UNIQUE,
            [ItemAction] [int] NOT NULL,        
            [ObjectId] [int] NOT NULL,
            [OperatorType] [int] NOT NULL,
        
            PRIMARY KEY NONCLUSTERED 
            (
               [ObjectId] ASC
            ),
        
            INDEX CIX CLUSTERED (ObjectId, OperatorType)    
          );
        

        【讨论】:

        • 我给了你 +1 的努力,但这对我在 sql server 2016 Msg 1018, Level 15, State 1, Line 11 Incorrect syntax near 'INDEX'. If this is intended as a part of a table hint, A WITH keyword and parenthesis are now required. See SQL Server Books Online for proper syntax. 上不起作用
        • 糟糕,我显然漏掉了一个逗号。我刚刚在 SQL 2016 (SP2 CU7) 上测试过
        • 太棒了,现在工作正常,我也在SQL 2016 (SP2 CU7)
        • 只是想知道为什么您在与 PRIMARY KEY 相同的列上有一个 UNIQUE 约束?确定作为主键已经强制执行唯一性吗?也许由于这种我不熟悉的新语法,我错过了一些东西?或者你的脚本只是为了说明这个概念?
        • 这只是为了说明您现在可以使用新语法对表类型执行的各种操作;你是对的,我的随机性导致了一个愚蠢的例子:)
        【解决方案4】:

        你可以像这样指定你的类型:

          CREATE TYPE [dbo].[DistCritGroupData] AS TABLE
          (
            [DistCritTypeId] [int] NOT NULL primary key,
            [ItemAction] [int] NOT NULL,        
            [ObjectId] [int] NOT NULL,
            [OperatorType] [int] NOT NULL
          );
        

        我从来不知道为什么数据库人员需要主键名称。它们应该被称为 xyz 表的主键。

        【讨论】:

        • “表 xyz 的主键”是有效标识符吗?它需要为 sys.objects 命名。
        • @gbn 它是绝对唯一的,如果必须,您可以评估系统表中生成的唯一名称。
        • 在使用源代码管理时,您需要一个命名键或约束。那么命名键或约束非常有用。
        • 命名 PK 约束在删除/重新创建 PK 时也很有帮助。删除时必须按名称引用 PK,因为生成的名称因环境而异,例如dev 和 prod 服务器,有一个脚本来删除/重新创建一个 PK,每次您必须 1. 命名约束或 2. 从 sys.key_constraints 中选择名称并使用动态 sql 删除约束(这很杂乱)。所以你应该命名 PK。参考:msdn.microsoft.com/en-us/library/ms190621.aspx
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-03
        • 1970-01-01
        • 2012-03-21
        • 2016-05-29
        • 2017-04-02
        • 1970-01-01
        相关资源
        最近更新 更多