Додайте первинний ключ до наявної таблиці


197

У мене є існуюча таблиця під назвою Persion. У цій таблиці я 5 стовпців:

  • persionId
  • Прізвище
  • ПМід
  • Підпис
  • Памт

Коли я створив цю таблицю, я встановив PersionIdі Pnameяк основний ключ .

Тепер я хочу включити ще один стовпець у первинний ключ - PMID. Як я можу написати ALTERзаяву для цього? (У мене вже є 1000 записів у таблиці)


8
Ти впевнений? це означає, що вам дозволяється мати дублікат personIdу вашій таблиці. Це, в свою чергу, означає, що якщо ви приєднаєтесь із таблиці транзакцій (багато) до цієї таблиці лише на цій клавіші, ви отримаєте повторювані записи, що призведе до "подвійного рахунку" записів транзакцій.
Nick.McDermaid

6
дійсно, це ДУЖЕ погана ідея. Ваш ПК може бути на "persionId", це все
Патрік Онорез

1
Я думав, що лише один стовпець у таблиці повинен бути встановлений як основний ключ?
Чарріс

1
@ChristopheHarris, іноді має сенс мати більше одного стовпця в якості основного ключа. Таблиця відносин «один до багатьох» або «багато-багато-багато», ймовірно, матиме 2 або більше стовпців зовнішніх ключів, що складають первинний ключ, оскільки однозначно ідентифікувати запис можливо лише тоді, коли ви знаєте значення всіх первинних ключів стовпчики. Однак у випадку з ОП малоймовірно, що це дійсно те, чого він хотів.
Крістен Хаммак

2
@Kristen Hammack Навіть у випадку відносин M2M, мабуть, краще мати проміжну таблицю окремим первинним ключем, а потім поставити унікальне разом обмеження на два зовнішні ключі.
kloddant

Відповіді:


191

скиньте обмеження і відтворіть його

alter table Persion drop CONSTRAINT <constraint_name>

alter table Persion add primary key (persionId,Pname,PMID)

редагувати:

ви можете знайти ім'я обмеження, скориставшись запитом нижче:

select OBJECT_NAME(OBJECT_ID) AS NameofConstraint
FROM sys.objects
where OBJECT_NAME(parent_object_id)='Persion'
and type_desc LIKE '%CONSTRAINT'

80

Я думаю, що щось подібне повинно працювати

-- drop current primary key constraint
ALTER TABLE dbo.persion 
DROP CONSTRAINT PK_persionId;
GO

-- add new auto incremented field
ALTER TABLE dbo.persion 
ADD pmid BIGINT IDENTITY;
GO

-- create new primary key constraint
ALTER TABLE dbo.persion 
ADD CONSTRAINT PK_persionId PRIMARY KEY NONCLUSTERED (pmid, persionId);
GO

1
Напевно, некластеризовані - це хороший варіант у випадку складених ПК для роботи на основі дати вставки, якщо це важливо для вас.
Шив

36
-- create new primary key constraint
ALTER TABLE dbo.persion 
ADD CONSTRAINT PK_persionId PRIMARY KEY NONCLUSTERED (pmid, persionId);

є кращим рішенням, тому що ви маєте контроль над іменем основного_ ключа.


Це краще, ніж просто використовувати

ALTER TABLE Persion ADD PRIMARY KEY(persionId,Pname,PMID)

які yeilds рандомізовані імена та можуть спричинити проблеми під час створення сценаріїв або порівняння баз даних


3
+1 - підкреслити функціональність, щоб назвати ваш основний ключ. Під час запуску скриптів оновлення, які відтворюють ПК, відновлюють ПК, бажано звертатися до названих ПК, ніж допитувати інформаційну схему, щоб з’ясувати ім’я
e_i_pi

27

Якщо ви додаєте обмеження первинного ключа

ALTER TABLE <TABLE NAME> ADD CONSTRAINT <CONSTRAINT NAME> PRIMARY KEY <COLUMNNAME>  

наприклад:

ALTER TABLE DEPT ADD CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO)

14

У вашій таблиці вже є первинний ключ. Ви не можете просто додати первинний ключ, інакше це призведе до помилки.Тому що є один первинний ключ для sql таблиці.

По-перше, вам потрібно скинути свій старий первинний ключ.

MySQL:

ALTER TABLE Persion
DROP PRIMARY KEY;

Доступ до SQL Server / Oracle / MS:

ALTER TABLE Persion
DROP CONSTRAINT 'constraint name';

Ви повинні знайти ім'я обмеження у вашій таблиці. Якщо ви створили ім’я обмеження під час створення таблиці, ви можете легко використовувати ім'я обмеження (наприклад: PK_Persion).

По-друге, Додати первинний ключ.

MySQL / SQL Server / Oracle / MS Access:

ALTER TABLE Persion ADD PRIMARY KEY (PersionId,Pname,PMID);

або кращий нижче

ALTER TABLE Persion ADD CONSTRAINT PK_Persion PRIMARY KEY (PersionId,Pname,PMID);

Це може встановити назву обмеження розробником. Простіше підтримувати стіл.

Я трохи заплутався, коли переглянув усі відповіді. Тому я досліджую якийсь документ, щоб знайти кожну деталь. Сподіваюся, що ця відповідь може допомогти іншим новачкам SQL.

Довідка: https://www.w3schools.com/sql/sql_primarykey.asp


4

Обмеження PRIMARY KEY однозначно ідентифікує кожен запис у таблиці бази даних. Первинні ключі повинні містити UNIQUE значення, а стовпець не може містити NULL значень.

  -- DROP current primary key 
  ALTER TABLE tblPersons DROP CONSTRAINT <constraint_name>
  Example:
  ALTER TABLE tblPersons 
  DROP CONSTRAINT P_Id;


  -- ALTER TABLE tblpersion
  ALTER TABLE tblpersion add primary key (P_Id,LastName)

4

Некромантування.
На всякий випадок, якщо хтось має настільки ж хорошу схему роботи, як і я ...
Ось як це зробити правильно:

У цьому прикладі назва таблиці - dbo.T_SYS_Language_Forms, а назва стовпця - LANG_UID

-- First, chech if the table exists...
IF 0 < (
    SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_TYPE = 'BASE TABLE'
    AND TABLE_SCHEMA = 'dbo'
    AND TABLE_NAME = 'T_SYS_Language_Forms'
)
BEGIN
    -- Check for NULL values in the primary-key column
    IF 0 = (SELECT COUNT(*) FROM T_SYS_Language_Forms WHERE LANG_UID IS NULL)
    BEGIN
        ALTER TABLE T_SYS_Language_Forms ALTER COLUMN LANG_UID uniqueidentifier NOT NULL 

        -- No, don't drop, FK references might already exist...
        -- Drop PK if exists (it is very possible it does not have the name you think it has...)
        -- ALTER TABLE T_SYS_Language_Forms DROP CONSTRAINT pk_constraint_name 
        --DECLARE @pkDropCommand nvarchar(1000) 
        --SET @pkDropCommand = N'ALTER TABLE T_SYS_Language_Forms DROP CONSTRAINT ' + QUOTENAME((SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
        --WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' 
        --AND TABLE_SCHEMA = 'dbo' 
        --AND TABLE_NAME = 'T_SYS_Language_Forms' 
        ----AND CONSTRAINT_NAME = 'PK_T_SYS_Language_Forms' 
        --))
        ---- PRINT @pkDropCommand 
        --EXECUTE(@pkDropCommand) 
        -- Instead do
        -- EXEC sp_rename 'dbo.T_SYS_Language_Forms.PK_T_SYS_Language_Forms1234565', 'PK_T_SYS_Language_Forms';

        -- Check if they keys are unique (it is very possible they might not be)        
        IF 1 >= (SELECT TOP 1 COUNT(*) AS cnt FROM T_SYS_Language_Forms GROUP BY LANG_UID ORDER BY cnt DESC)
        BEGIN

            -- If no Primary key for this table
            IF 0 =  
            (
                SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
                WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' 
                AND TABLE_SCHEMA = 'dbo' 
                AND TABLE_NAME = 'T_SYS_Language_Forms' 
                -- AND CONSTRAINT_NAME = 'PK_T_SYS_Language_Forms' 
            )
                ALTER TABLE T_SYS_Language_Forms ADD CONSTRAINT PK_T_SYS_Language_Forms PRIMARY KEY CLUSTERED (LANG_UID ASC)
            ;

        END -- End uniqueness check
        ELSE
            PRINT 'FSCK, this column has duplicate keys, and can thus not be changed to primary key...' 
    END -- End NULL check
    ELSE
        PRINT 'FSCK, need to figure out how to update NULL value(s)...' 
END 

Дуже хороший пункт про те, що "не впадай, посилання на FK вже можуть існувати". Інші відповіді для мене не спрацювали.
sgryzko

2

Спробуйте це-

ALTER TABLE TABLE_NAME DROP INDEX `PRIMARY`, ADD PRIMARY KEY (COLUMN1, COLUMN2,..);

1

Спробуйте скористатися цим кодом:

ALTER TABLE `table name` 
    CHANGE COLUMN `column name` `column name` datatype NOT NULL, 
    ADD PRIMARY KEY (`column name`) ;

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.