Mevcut tabloya birincil anahtar ekle


197

Adında mevcut bir tablo var Persion. Bu tabloda 5 sütun var:

  • persionId
  • pname
  • PMID
  • Pdescription
  • Pamt

Bu tabloyu oluşturduğumda, PersionIdve anahtarını birincil anahtarPname olarak ayarladım .

Şimdi birincil anahtara - PMID - bir sütun daha eklemek istiyorum. Bunu ALTERyapmak için nasıl bir ifade yazabilirim ? (Tabloda zaten 1000 kayıt var)


8
Emin misiniz? Bu personId, tablonuzda yinelenmesine izin verdiğiniz anlamına gelir . Bu da, bir işlem (çok) tür tablosundan yalnızca bu anahtar üzerinde bu tabloya katılırsanız, yinelenen kayıtlar alacağınız ve işlem kayıtlarının 'iki kez sayılmasına' yol açacağı anlamına gelir.
Nick.McDermaid

6
gerçekten, bu ÇOK kötü bir fikir. PK'nız "persionId" üzerinde olabilir, hepsi bu
Patrick Honorez

1
Bir tablodaki sadece bir sütun birincil anahtar olarak ayarlanması gerektiğini düşündüm?
CHarris

1
@ChristopheHarris, bazen birincil anahtar olarak birden fazla sütuna sahip olmak mantıklıdır. Bire çok veya çoktan çoğa ilişki tablosunda, birincil anahtarı oluşturan 2 veya daha fazla yabancı anahtar sütunu olabilir, çünkü yalnızca birincil anahtarın tüm değerlerini biliyorsanız bir kaydı benzersiz olarak tanımlamak mümkündür sütunlar. Ancak, OP'nin durumunda, bunun gerçekten istediği şey olması pek olası değildir.
Kristen Hammack

2
@Kristen Hammack M2M ilişkileri söz konusu olduğunda bile, ara tablonun ayrı bir birincil anahtara sahip olması ve daha sonra iki yabancı anahtara benzersiz bir birlikte kısıtlaması koyması daha iyidir.
kloddant

Yanıtlar:


191

kısıtlamayı bırakın ve yeniden oluşturun

alter table Persion drop CONSTRAINT <constraint_name>

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

Düzenle:

kısıtlama adını aşağıdaki sorguyu kullanarak bulabilirsiniz:

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

80

Bunun gibi bir şeyin çalışması gerektiğini düşünüyorum

-- 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
Muhtemelen kümelenmemiş, sizin için önemliyse, ekleme tarihi bazında performans için bileşik PK'larda iyi bir seçenektir.
Shiv

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

birincil_anahtarı üzerinde kontrol sahibi olduğunuz için daha iyi bir çözümdür.


Sadece kullanmaktan daha iyi

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

rastgele adları isimlendirir ve veritabanlarını oluştururken veya veritabanlarını karşılaştırırken sorunlara neden olabilir


3
Birincil anahtarınızı adlandırmak üzere işlevselliği vurgulamak için +1. PK'ları yeniden yaratan güncelleme komut dosyaları çalıştırdığınızda, adı bulmak için bilgi şemasını sorgulamak yerine adlandırılmış PK'lara vurmak tercih edilir
e_i_pi 12:18

27

Birincil anahtar kısıtlaması eklerseniz

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

Örneğin:

ALTER TABLE DEPT ADD CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO)

14

Tablonuzda zaten birincil anahtar var. Yalnızca birincil anahtar ekleyemezsiniz, aksi takdirde hataya neden olur. Çünkü sql tablosu için bir birincil anahtar var.

İlk olarak, eski birincil anahtarınızı bırakmanız gerekir.

MySQL:

ALTER TABLE Persion
DROP PRIMARY KEY;

SQL Server / Oracle / MS Erişimi:

ALTER TABLE Persion
DROP CONSTRAINT 'constraint name';

Kısıtlama adını tablonuzda bulmanız gerekir. Tablo oluştururken kısıtlama adı verdiyseniz, kısıtlama adını kolayca kullanabilirsiniz (örn: PK_Persion).

İkinci olarak, birincil anahtar ekleyin.

MySQL / SQL Server / Oracle / MS Erişimi:

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

ya da aşağıdaki en iyisi

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

Bu, geliştirici tarafından kısıtlama adı ayarlayabilir. Masayı korumak daha kolaydır.

Bütün cevaplara baktığımda biraz kafam karıştı. Bu yüzden her ayrıntıyı bulmak için bir belge araştırıyorum. Umarım bu cevap diğer SQL acemi yardımcı olabilir.

Referans: https://www.w3schools.com/sql/sql_primarykey.asp


4

PRIMARY KEY kısıtlaması, veritabanı tablosundaki her kaydı benzersiz şekilde tanımlar. Birincil anahtarlar BENZERSİZ değerler içermeli ve sütun NULL Değerler içeremez.

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

Necromancing.
Herhangi birinin benimle çalışmak için iyi bir şeması olması durumunda ...
İşte doğru şekilde nasıl yapılacağı:

Bu örnekte, tablo adı dbo.T_SYS_Language_Forms ve sütun adı 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 

'Düşmeyin, FK referansları zaten mevcut olabilir' hakkında çok iyi bir nokta. Bu yüzden diğer cevaplar benim için işe yaramadı.
sgryzko

2

Lütfen bunu deneyin-

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

1

Bu kodu kullanmayı deneyin:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.