Как удалить первичный ключ, у которого нет имени?

#sql-server

#sql-сервер

Вопрос:

Я использую SQL Server. Есть ли способ удалить первичный ключ, у которого нет имени?

Комментарии:

1. У него должно быть имя; возможно, сгенерированное машиной, но у него есть имя….

Ответ №1:

У него есть имя. Даже если вы не назовете его явно, SQL Server автоматически создаст имя с префиксом PK на основе имени таблицы и object_id ограничения.

Вы можете использовать следующий запрос, чтобы узнать, что это такое.

 SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE='PRIMARY KEY' AND TABLE_SCHEMA='dbo' AND TABLE_NAME='T'
  

Имя ограничения требуется в грамматике для DROP CONSTRAINT операции

 ALTER TABLE [ database_name . [ schema_name ] . | schema_name . ] table_name 
{ 
   ....
    DROP 
    { 
        [ CONSTRAINT ] constraint_name 
        [ WITH ( <drop_clustered_constraint_option> [ ,...n ] ) ]
        | COLUMN column_name 
    } [ ,...n ] 
  

Комментарии:

1. могу ли я удалить первичный ключ, не используя его имя?

2. @vatspoo: нет, но скрипт Мартина говорит вам, как узнать имя!

3. вы могли бы прибегнуть к динамическому sql, нет?

4. БЕЛЛИСИМО. но кто тратит столько времени на поиск бесхозного (безымянного) первичного ключа и пишет столько кода.

Ответ №2:

У первичного ключа всегда есть имя. Если вы не указали его в инструкции ‘create table’ или ‘alter table’, имя ключа генерируется автоматически.
В приведенном ниже запросе замените X на имя вашей таблицы и запустите скрипт.
Это приведет к удалению первичного ключа.

 declare @TableName sysname = 'X'

declare @PrimaryKeyName sysname = (
    select name
    from sys.key_constraints
    where type = 'PK' and parent_object_id = object_id(@TableName))

execute ('alter table '   @TableName   ' drop constraint '   @PrimaryKeyName)   
  

Всегда полезно указывать явные имена для ограничений, потому что если вы запустите скрипт ‘create / alter table’ в разных базах данных, у всех них будет создано разное имя ограничения.
Позже, когда вам понадобится удалить ограничения, вам нужно будет запустить этот обходной сценарий, вместо этого просто выполнив простую инструкцию ‘alter table drop constraint’.

Ответ №3:

 CREATE TABLE #Tempbox (Id int primary key identity(1,1), Name varchar(200) unique) 
  

создавая таблицу с идентификатором столбца и именем, обратите внимание, что у нее нет имени ограничения.

Что ж, если вы не задаете имя ограничения для столбца, sql server предоставляет свое собственное уникальное имя ограничения по умолчанию для ограничения, например primary key, unique и так далее.

 1. Let's insert some value in our #Tempbox table

1. insert into #tempbox values ('Abc')
2. insert into #tempbox values ('Abc')
  

ошибка с нарушением уникального ключа, отображаемая sql server вместе с именем ограничения.

 **Msg 2627, Level 14, State 1, Line 5
Violation of UNIQUE KEY constraint **'UQ__#Tempbox__737584F6A146D511'**. Cannot insert duplicate key in object 'dbo.#Tempbox'. The duplicate key value is (dsaf).
The statement has been terminated.**
  

теперь у вас есть имя ограничения .. которое ‘UQ__#Tempbox__737584F6A146D511’

теперь давайте удалим столбец с ограничением. Помните, что вы не можете удалить столбец, если в нем используется ограничение, поэтому для удаления этого столбца вам придется удалить первое ограничение и следующий столбец.

ALTER TABLE #Tempbox drop constraint UQ__#Tempbox__737584F6A146D511; -- constraint is dropped

теперь удалите столбец

 alter table #tempbox drop column Name
  

Теперь используйте ту же процедуру для столбца первичного ключа

 INSERT INTO #Tempbox (Id, Name) VALUES (1,'Abc')
INSERT INTO #Tempbox (Id, Name) VALUES (1,'Abc')
  

Ошибка :

 Msg 2627, Level 14, State 1, Line 3
Violation of PRIMARY KEY constraint **'PK__#Tempbox__3214EC07B3D09900'**. Cannot insert duplicate key in object 'dbo.#Tempbox'. The duplicate key value is (1).
The statement has been terminated.
  

отбросьте ограничение и удалите столбец.

Другой способ найти имя ограничения..

 USE Adventure 

SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE='PRIMARY KEY' AND TABLE_SCHEMA='pERSON' AND TABLE_NAME='PERSON'