2012-01-13 43 views
34

CẬP NHẬTThay đổi cột khóa chính trong SQL Server

Dưới đây là những hạn chế như là kết quả của truy vấn

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 

Dưới đây là kết quả của truy vấn

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 CẬP NHẬT

Máy chủ lưu trữ của tôi cung cấp giao diện cho SQL Server DB của tôi thông qua ASP.NET Enterprise Manager.

Tôi có 3 cột trong bảng history tôi:

  • userId (key, int, NULL không được phép)
  • name (chìa khóa, chuỗi, NULL không được phép)
  • id (không quan trọng, int, NULL được phép)

Tôi muốn đặt cột id là khóa duy nhất.

Để làm điều đó, tôi tin rằng tôi cần phải:

  1. Hãy chắc chắn rằng không có NULLs trong cột đó cho bất kỳ hàng
  2. Đặt cột để không cho phép null
  3. Thêm cột như một chính chủ chốt
  4. Tháo 2 cột khác như phím

Tuy nhiên, khi tôi sử dụng giao diện người dùng được cung cấp, nó không bao giờ làm việc. Đôi khi nó sẽ chỉ trông giống như nó cố gắng để làm một cái gì đó nhưng nó không bao giờ thay đổi khi tôi làm mới xem các cột. Nó đôi khi tạo ra một bảng tạm thời có vẻ như nó đã cố gắng để làm một số hoạt động, nhưng điều đó không bao giờ được sao chép/ghi đè lên bảng gốc mà tôi đang cố gắng thay đổi.

Khi tôi thử sử dụng truy vấn, các thay đổi cũng không hiển thị. Dưới đây là các truy vấn tôi nghĩ mình cần:

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 

Tôi chỉ nhận được nỗ lực không cho phép NULL và thêm khóa chính cho cột id. Nó dường như không hoạt động. Ai đó có thể chỉ cho tôi đi đúng hướng? Cảm ơn!

+0

Bạn có nhận được thông báo lỗi không? –

+0

bạn nên bỏ các ràng buộc đầu tiên –

+0

không, tôi không nhận được bất kỳ thông báo lỗi nào với truy vấn. Với UI, tôi nhận được lỗi liên quan đến việc thiết lập cột id thành một khóa khi nó cho phép null, nhưng không có lỗi khi cố gắng không cho phép null. – ckbhodge

Trả lời

55

Giả sử rằng ràng buộc khoá chính hiện tại của bạn được gọi là pk_history, bạn có thể thay thế các dòng sau:

ALTER TABLE history ADD PRIMARY KEY (id) 

ALTER TABLE history 
DROP CONSTRAINT userId 
DROP CONSTRAINT name 

với những:

ALTER TABLE history DROP CONSTRAINT pk_history 

ALTER TABLE history ADD CONSTRAINT pk_history PRIMARY KEY (id) 

Nếu bạn không biết những gì tên của PK là, bạn có thể tìm thấy nó bằng truy vấn sau:

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

cảm ơn.) (Sau khi sử dụng truy vấn của bạn để tìm tên PK: "PK_history") nhưng giao diện người dùng vẫn hiển thị 2 cột gốc làm khóa và cột id không có, tôi không nhận được thông báo lỗi, có lẽ do cột id vẫn cho phép null? – ckbhodge

+1

Bạn có làm mới trong giao diện người dùng không? Tôi nghi ngờ rằng chúng có thể là khóa ngoài và không phải là PK. Bạn có thể 'SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'history'' để xác định ràng buộc nào của mỗi cột trong bảng được liên kết với. –

+0

Đúng, làm mới giao diện người dùng (thậm chí đóng tab và mở lại). Cập nhật kết quả của truy vấn trên ở đầu câu hỏi Cảm ơn! – ckbhodge

0

Necromancing.
Có vẻ bạn có giống như tốt một sơ đồ để làm việc với như tôi ... Sau đây là cách để làm điều đó một cách chính xác:

Trong ví dụ này, tên bảng là dbo.T_SYS_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 
     -- 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 
Các vấn đề liên quan