Подтвердить что ты не робот

Как добавить индекс или первичный ключ к определенному пользователем типу таблицы в SQL Server?

У меня есть этот пользовательский тип, который я бы хотел добавить к первичному ключу или индексу:

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
    )        
  );

В Обозревателе объектов в моем определяемом пользователем типе таблицы я вижу разделы "Столбцы", "Ключи", "Ограничения" и "Индексы". Вопросы: как я добавляю ключ или индекс?

4b9b3361

Ответ 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 для таблиц, но вы не можете их назвать. Этот вид имеет смысл, поскольку вы собираетесь создавать несколько объектов одного типа, и единственный раз, когда вы захотите поработать с этими ограничениями, будет изменение всего типа таблицы.

Вы также не можете определить индексы, так как они в первую очередь являются артефактом физического хранилища.

Ответ 3

Вы можете указать свой тип следующим образом:

  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.

Ответ 4

Стоит отметить, что теперь вы можете добавлять определенные индексы в табличные типы в 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 
    (
       [DistCritTypeId] ASC
    ),

    INDEX CIX CLUSTERED (ObjectId, OperatorType)    
  );