Thêm khóa chính vào bảng hiện có


193

Tôi có một bảng hiện có tên Persion. Trong bảng này tôi có 5 cột:

  • persionId
  • Tên
  • PMid
  • Mô tả
  • Chà

Khi tôi tạo bảng này, tôi đặt PersionIdPnamelàm khóa chính .

Bây giờ tôi muốn bao gồm một cột nữa trong khóa chính - PMID. Làm thế nào tôi có thể viết một ALTERtuyên bố để làm điều này? (Tôi đã có 1000 hồ sơ trong bảng)


8
Bạn có chắc không? điều này có nghĩa là bạn được phép có bản sao personIdtrong bảng của mình. Đến lượt điều này có nghĩa là nếu bạn tham gia từ một loại bảng giao dịch (nhiều) vào bảng này trên khóa này, bạn sẽ nhận được các bản ghi trùng lặp, dẫn đến 'đếm gấp đôi' các bản ghi giao dịch.
Nick.McDilyn

6
Thật vậy, đây là một ý tưởng RẤT xấu. PK của bạn có thể là "persionId", đó là
Patrick Honorez

1
Tôi nghĩ chỉ nên đặt một cột trong bảng làm khóa chính?
CHarris

1
@ChristopheHarris, đôi khi nó có ý nghĩa khi có nhiều hơn một cột làm khóa chính. Bảng quan hệ một-nhiều hoặc nhiều-nhiều có thể sẽ có 2 hoặc nhiều cột khóa ngoại tạo thành khóa chính, vì chỉ có thể xác định duy nhất một bản ghi nếu bạn biết các giá trị của tất cả khóa chính cột. Tuy nhiên, trong trường hợp của OP, không chắc đây thực sự là điều anh ta muốn.
Võng Kristen

2
@Kristen Võng Ngay cả trong trường hợp mối quan hệ M2M, có lẽ tốt hơn là có bảng trung gian có một khóa chính riêng biệt và sau đó đặt một ràng buộc duy nhất với nhau trên hai khóa ngoại.
kloddant

Câu trả lời:


190

thả ràng buộc và tạo lại nó

alter table Persion drop CONSTRAINT <constraint_name>

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

biên tập:

bạn có thể tìm thấy tên ràng buộc bằng cách sử dụng truy vấn bên dưới:

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

80

Tôi nghĩ rằng một cái gì đó như thế này sẽ làm việc

-- 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
Có lẽ không phân cụm là một lựa chọn tốt trong trường hợp PK tổng hợp để thực hiện trên cơ sở ngày chèn nếu điều đó quan trọng đối với bạn.
Shiv

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

là một giải pháp tốt hơn bởi vì bạn có quyền kiểm soát việc đặt tên của tệp chính_key.


Nó tốt hơn là chỉ sử dụng

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

Những cái tên ngẫu nhiên và có thể gây ra vấn đề khi viết kịch bản hoặc so sánh cơ sở dữ liệu


3
+1 để làm nổi bật tính chính xác để đặt tên cho khóa chính của bạn. Khi bạn đang chạy các tập lệnh cập nhật tạo lại PK, bạn nên đánh PK có tên hơn là phải thẩm vấn lược đồ thông tin để tìm ra tên
e_i_pi

27

Nếu bạn thêm ràng buộc khóa chính

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

ví dụ:

ALTER TABLE DEPT ADD CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO)

13

Đã có một khóa chính trong bảng của bạn. Bạn không thể chỉ thêm khóa chính, nếu không sẽ gây ra lỗi. Bởi vì có một khóa chính cho bảng sql.

Đầu tiên, bạn phải bỏ khóa chính cũ của mình.

MySQL:

ALTER TABLE Persion
DROP PRIMARY KEY;

Truy cập máy chủ SQL / Oracle / MS:

ALTER TABLE Persion
DROP CONSTRAINT 'constraint name';

Bạn phải tìm tên ràng buộc trong bảng của bạn. Nếu bạn đã đặt tên ràng buộc khi bạn tạo bảng, bạn có thể dễ dàng sử dụng tên ràng buộc (ví dụ: PK_Persion).

Thứ hai, Thêm khóa chính.

Truy cập MySQL / SQL / Oracle / MS:

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

hoặc cái tốt hơn dưới đây

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

Điều này có thể đặt tên ràng buộc của nhà phát triển. Dễ dàng hơn để duy trì bảng.

Tôi đã có một chút bối rối khi tôi đã xem tất cả các câu trả lời. Vì vậy, tôi nghiên cứu một số tài liệu để tìm mọi chi tiết. Hy vọng câu trả lời này có thể giúp người mới bắt đầu SQL.

Tham khảo: https://www.w3schools.com/sql/sql_primarykey.asp


4

Ràng buộc PRIMARY KEY xác định duy nhất mỗi bản ghi trong bảng cơ sở dữ liệu. Các khóa chính phải chứa các giá trị UNIQUE và cột không thể chứa Giá trị 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

Necromance.
Chỉ trong trường hợp bất kỳ ai cũng có một lược đồ tốt để làm việc với tôi ...
Đây là cách thực hiện chính xác:

Trong ví dụ này, tên bảng là dbo.T_SYS_L Language_Forms và tên cột là 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 

Điểm rất hay về 'không bỏ, các tham chiếu FK có thể đã tồn tại'. Các câu trả lời khác đã không làm việc cho tôi vì điều này.
sgryzko ngày

2

Hãy thử cái này-

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

1

Hãy thử sử dụng mã này:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.