Dodaj klucz podstawowy do istniejącej tabeli

196

Mam istniejącą tabelę o nazwie Persion. W tej tabeli mam 5 kolumn:

  • persionId
  • Pseudonim
  • PMid
  • Opis
  • Pamt

Kiedy utworzyłem tę tabelę, ustawiłem PersionIdi Pnamejako klucz podstawowy .

Chcę teraz dołączyć jeszcze jedną kolumnę do klucza podstawowego - PMID. Jak mogę napisać ALTERoświadczenie, aby to zrobić? (Mam już 1000 rekordów w tabeli)

sójka
źródło
8
Jesteś pewny? oznacza to, że możesz mieć duplikat personIdw swoim stole. To z kolei oznacza, że ​​jeśli dołączysz z tabeli typu transakcji (wielu) do tej tabeli na tym samym kluczu, otrzymasz duplikaty rekordów, co prowadzi do „podwójnego liczenia” rekordów transakcji.
Nick.McDermaid
6
w rzeczywistości jest to BARDZO zły pomysł. Twój PK powinien być ustawiony na „persionId”, to wszystko
Patrick Honorez,
1
Myślałem, że jako klucz podstawowy należy ustawić tylko jedną kolumnę w tabeli?
CHarris
1
@ChristopheHarris, czasem warto mieć więcej niż jedną kolumnę jako klucz podstawowy. Tabela relacji jeden do wielu lub wiele do wielu będzie prawdopodobnie zawierać 2 lub więcej kolumn kluczy obcych tworzących klucz podstawowy, ponieważ możliwe jest jednoznaczne zidentyfikowanie rekordu tylko wtedy, gdy znasz wartości wszystkich kluczy podstawowych kolumny. Jednak w przypadku PO mało prawdopodobne jest, aby tego właśnie chciał.
Kristen Hammack
2
@Kristen Hammack Nawet w przypadku relacji M2M prawdopodobnie lepiej jest, aby tabela pośrednia miała osobny klucz główny, a następnie nałożyła unikalne ograniczenie na dwa klucze obce.
kloddant

Odpowiedzi:

192

usuń ograniczenie i utwórz je ponownie

alter table Persion drop CONSTRAINT <constraint_name>

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

edytować:

nazwę ograniczenia można znaleźć, korzystając z zapytania poniżej:

select OBJECT_NAME(OBJECT_ID) AS NameofConstraint
FROM sys.objects
where OBJECT_NAME(parent_object_id)='Persion'
and type_desc LIKE '%CONSTRAINT'
Joe G Joseph
źródło
80

Myślę, że coś takiego powinno działać

-- 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
TI
źródło
1
Prawdopodobnie nieklastrowany jest dobrą opcją w przypadku kompozytowych PK dla wydajności na podstawie daty wstawienia, jeśli jest to dla Ciebie ważne.
Shiv
36
-- create new primary key constraint
ALTER TABLE dbo.persion 
ADD CONSTRAINT PK_persionId PRIMARY KEY NONCLUSTERED (pmid, persionId);

jest lepszym rozwiązaniem, ponieważ masz kontrolę nad nazwą klucza podstawowego.


To lepsze niż tylko używanie

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

który tworzy losowe nazwy i może powodować problemy podczas tworzenia skryptów lub porównywania baz danych

użytkownik3675542
źródło
3
+1 za wyróżnienie funkcji nazwania twojego klucza podstawowego. Podczas uruchamiania skryptów aktualizacyjnych, które usuwają i odtwarzają PK, lepiej jest nacisnąć nazwane PK niż przesłuchać schemat informacyjny, aby ustalić nazwę
e_i_pi
27

Jeśli dodasz ograniczenie klucza podstawowego

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

na przykład:

ALTER TABLE DEPT ADD CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO)
K GANGA
źródło
13

W twojej tabeli znajduje się już klucz podstawowy. Nie możesz po prostu dodać klucza podstawowego, w przeciwnym razie spowoduje błąd. Ponieważ istnieje jeden klucz podstawowy dla tabeli sql.

Najpierw musisz upuścić swój stary klucz podstawowy.

MySQL:

ALTER TABLE Persion
DROP PRIMARY KEY;

SQL Server / Oracle / MS Access:

ALTER TABLE Persion
DROP CONSTRAINT 'constraint name';

Musisz znaleźć nazwę ograniczenia w swojej tabeli. Jeśli podałeś nazwę ograniczenia podczas tworzenia tabeli, możesz łatwo użyć nazwy ograniczenia (np. PK_Persion).

Po drugie, dodaj klucz podstawowy.

MySQL / SQL Server / Oracle / MS Access:

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

lub lepszy poniżej

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

To może ustawić nazwę ograniczenia przez programistę. Łatwiej jest utrzymać stół.

Trochę się pogubiłem, kiedy spojrzałem na wszystkie odpowiedzi. Przeszukuję jakiś dokument, aby znaleźć każdy szczegół. Mam nadzieję, że ta odpowiedź może pomóc innym początkującym w SQL.

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

劉鎮 瑲
źródło
4

Ograniczenie KLUCZ PODSTAWOWY jednoznacznie identyfikuje każdy rekord w tabeli bazy danych. Klucze podstawowe muszą zawierać UNIKALNE wartości, a kolumna nie może zawierać wartości 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)
Mike Clark
źródło
4

Nekromancja.
Na wypadek, gdyby ktoś miał tak dobry schemat do pracy jak ja ...
Oto jak to zrobić poprawnie:

W tym przykładzie nazwa tabeli to dbo.T_SYS_Language_Forms, a nazwa kolumny to 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 
Stefan Steiger
źródło
Bardzo dobra uwaga na temat „nie upuszczaj, odniesienia do FK mogą już istnieć”. Inne odpowiedzi nie działały dla mnie z tego powodu.
sgryzko
2

Spróbuj tego-

ALTER TABLE TABLE_NAME DROP INDEX `PRIMARY`, ADD PRIMARY KEY (COLUMN1, COLUMN2,..);
Samir
źródło
1

Spróbuj użyć tego kodu:

ALTER TABLE `table name` 
    CHANGE COLUMN `column name` `column name` datatype NOT NULL, 
    ADD PRIMARY KEY (`column name`) ;
Rekha Rajan
źródło
1
ALTER TABLE TABLE_NAME ADD PRIMARY KEY(`persionId`,`Pname`,`PMID`)
Harry Singh
źródło