2012-08-03 149 views
101

我有一个名为Persion的现有表。在这个表中我有5列:将主键添加到现有表

  • persionId
  • PNAME
  • PMID
  • Pdescription
  • PAMT

当我创造了这个表,我设置PersionId和PNAME作为首要的关键。

我现在想要在主键 - PMID中添加一列。我怎样才能写一个ALTER声明来做到这一点? (我已经有1000个表中的记录)

+5

你确定吗?这意味着您可以在表格中复制'personId'。这反过来意味着,如果您从一个事务(许多)类型的表中单独加入此表中,那么您将获得重复记录,从而导致对事务记录的“重复计数”。 – 2015-02-18 05:34:05

+4

确实,这是一个非常糟糕的主意。你的PK应该是“persionId”,就是这样吧 – 2015-11-12 09:56:07

+1

我认为表中只有一列应该被设置为主键? – CHarris 2016-07-21 21:57:41

回答

117

下降的约束,然后重新创建

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' 
+0

在添加主键时不要忘记括号'(...)'。 – Avi 2016-02-22 04:49:05

45

我觉得像这样应该可以工作

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

为什么PK上的NONCLUSTERED选项? – 2015-11-12 09:54:38

+0

对于插入日期基础上的性能,如果这对您很重要,则非聚簇可能是一种很好的选择。 – Shiv 2017-02-10 05:23:03

3

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) 
19
-- create new primary key constraint 
ALTER TABLE dbo.persion 
ADD CONSTRAINT PK_persionId PRIMARY KEY NONCLUSTERED (pmid, persionId); 

是一个更好的解决方案,因为你必须在primary_key的命名控制。


这不仅仅是使用

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

脚本进行或比较数据库

+0

请忽略[:]注意自己:'ALTER TABLE Person DROP CONSTRAINT ' – 2017-08-22 03:02:20

2

Necromancing时yeilds随机的名字,并可能导致问题的更好。
万一有人有良好的模式与作为我...
下面是如何正确地做它的工作:

在这个例子中,表名是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 
+0

非常好的一点关于'不要丢弃,FK引用可能已经存在'。因为这个,其他答案对我来说不起作用。 – sgryzko 2017-03-03 16:47:33

0

尝试使用此代码:如果您添加主键约束

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

例如

ALTER TABLE `table name` 
    CHANGE COLUMN `column name` `column name` datatype NOT NULL, 
    ADD PRIMARY KEY (`column name`) ; 
0
ALTER TABLE TABLE_NAME ADD PRIMARY KEY(`persionId`,`Pname`,`PMID`) 
11

ALTER TABLE DEPT ADD CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO)