2012-01-13 63 views
34

UPDATE在SQL Server更改主键列

这里是约束作为查询

SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'history' 

CONSTRAINT_NAME COLUMN_NAME ORDINAL_POSITION 
PK_history  userKey  1 
PK_history  name   2 

这里的结果是查询

SELECT * 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
WHERE TABLE_NAME = 'history' 

CONSTRAINT_NAME CONSTRAINT_TYPE IS_DEFERRABLE INITIALLY_DEFERRED 
PK_history  PRIMARY KEY  NO    NO 

END的结果UPDATE

我的主机通过ASP.NET企业管理器为我的SQL Server数据库提供了一个接口。

我有我history表3列:

  • userId(键,INT,NULL不允许)
  • name(键,字符串,NULL不允许)
  • id(不是关键, int,NULL允许)

我想让id列成为唯一的关​​键。

为了做到这一点,我相信我需要:

  1. 确保没有在该列没有空值的任何行
  2. 把字段设置为不允许NULL
  3. 添加列作为主键
  4. 删除其他2列,键

然而,当我使用所提供的用户界面,它永远不会奏效。有时它会看起来像试图做某些事情,但当我刷新列的视图时,它不会改变。它偶尔会创建一个临时表,它看起来像试图执行某些操作,但从不会被复制/覆盖正在尝试更改的原始表。

当我尝试使用查询时,更改也不会显示出来。这里是我认为我需要的查询:

SELECT * from history WHERE id is NULL  <---- This shows 0 results 

    ALTER TABLE history 
    ALTER COLUMN id int NOT NULL 

    ALTER TABLE history ADD PRIMARY KEY (id) 

    ALTER TABLE history 
    DROP CONSTRAINT userId 
    DROP CONSTRAINT name 
    GO 

我只尝试了禁止NULL并为id列添加主键。它似乎没有工作。有人能指引我朝着正确的方向吗?谢谢!

+0

您是否收到错误信息? – 2012-01-13 00:27:18

+0

你应该先删除约束条件 – 2012-01-13 00:30:48

+0

nope,我没有收到任何与查询有关的错误消息。使用用户界面时,我得到的错误是将ID列设置为一个键,当它允许空值时,但在尝试禁用空值时没有错误。 – ckbhodge 2012-01-13 00:37:13

回答

55

假设您目前的主键约束被称为pk_history,您可以替换以下行:

ALTER TABLE history ADD PRIMARY KEY (id) 

ALTER TABLE history 
DROP CONSTRAINT userId 
DROP CONSTRAINT name 

这些:

ALTER TABLE history DROP CONSTRAINT pk_history 

ALTER TABLE history ADD CONSTRAINT pk_history PRIMARY KEY (id) 

如果你不知道的什么名字PK是,您可以通过以下查询找到它:

SELECT * 
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
WHERE TABLE_NAME = 'history' 
+0

谢谢。试过这些(在使用你的查询找到PK名称:“PK_history”),但用户界面仍然显示原始的2列作为键和id列没有,我没有得到一个错误信息,也许这是由于ID列仍然允许空值? – ckbhodge 2012-01-13 00:49:27

+1

你在UI中刷新了吗?我强烈怀疑他们可能是外键,而不是PK。你可以'SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME ='history''来确定表格中每一列与哪个约束相关联。 – 2012-01-13 00:54:29

+0

是的,刷新了UI(甚至关闭了标签并重新打开)。在问题顶部更新了上述查询的结果,谢谢! – ckbhodge 2012-01-13 01:06:00

0

Necromancing。
它看起来你有一样好一个模式与作为我... 下面是如何正确地做它的工作:

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

      -- Adding foreign key 
      IF 0 = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_NAME = 'FK_T_ZO_SYS_Language_Forms_T_SYS_Language_Forms') 
       ALTER TABLE T_ZO_SYS_Language_Forms WITH NOCHECK ADD CONSTRAINT FK_T_ZO_SYS_Language_Forms_T_SYS_Language_Forms FOREIGN KEY(ZOLANG_LANG_UID) REFERENCES T_SYS_Language_Forms(LANG_UID); 
     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