SQL Server thêm khóa chính tăng tự động vào bảng hiện có


253

Như tiêu đề, tôi có một bảng hiện có đã được điền với 150000 bản ghi. Tôi đã thêm một cột Id (hiện tại là null).

Tôi giả sử tôi có thể chạy truy vấn để điền vào cột này với các số tăng dần, sau đó đặt làm khóa chính và bật tăng tự động. Đây có phải là cách chính xác để tiến hành? Và nếu vậy, làm thế nào để tôi điền vào những con số ban đầu?

Câu trả lời:


429

Không - bạn phải thực hiện theo cách khác: thêm nó ngay từ khi đang di chuyển INT IDENTITY- nó sẽ chứa đầy các giá trị nhận dạng khi bạn làm điều này:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY

và sau đó bạn có thể biến nó thành khóa chính:

ALTER TABLE dbo.YourTable
   ADD CONSTRAINT PK_YourTable
   PRIMARY KEY(ID)

hoặc nếu bạn thích làm tất cả trong một bước:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY
       CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED

2
Đây là một câu trả lời thực sự tốt, nhưng làm thế nào tôi có thể thay đổi số nguyên bắt đầu từ 1 thành 1000? Tôi muốn bắt đầu đếm ở 1000. Tôi nghi ngờ mình có thể sử dụng ALTER TABLE ORDER ALTER COLUMN ORDERNO RESTART WITH 1nhưng tôi không muốn dùng thử mà không kiểm tra với chuyên gia :) Tham khảo. pic.dhe.ibm.com/infocenter/iseries/v7r1m0/
user1477388

3
Tôi mới sử dụng cái này và có vẻ như nó đã hoạt độngalter table attachments add ATTACHMENT_NUMBER int identity (1000, 1)
user1477388

1
@stom: nếu bạn không chỉ định bất cứ điều gì, seed = 1 và gia tăng = 1 sẽ được sử dụng - đây là cài đặt được sử dụng thường xuyên nhất. Nếu bạn đã tạo một bảng như thế này - nó sẽ hoạt động tốt. Nhưng tôi khuyên bạn nên luôn luôn xác định rõ ràng hạt giống và gia tăng trong các tập lệnh SQL của mình - đặc biệt là đối với một trang web lớn hơn. Đó chỉ là thực hành tốt.
marc_s

1
@stom: tốt, PRIMARY KEYngụ ý đó NOT NULLlà đúng chỗ - vì vậy một lần nữa - nó không thực sự cần thiết. Nhưng tôi thích rõ ràng hơn và vì vậy tôi luôn luôn có mặt NOT NULLở đó, chỉ cần hoàn toàn rõ ràng
marc_s

3
@ turbo88: khi bạn xác định PRIMARY KEY, chỉ mục cụm được tạo tự động cho bạn (trừ khi bạn chỉ định rõ ràng NONCLUSTERED)
marc_s

19

Bạn không thể "bật" SẮC: đó là xây dựng lại bảng.

Nếu bạn không quan tâm đến thứ tự số, bạn sẽ thêm cột, KHÔNG PHẢI, với IDENTITY trong một lần. Hàng 150k không nhiều.

Nếu bạn cần giữ một số thứ tự số, sau đó thêm các số cho phù hợp. Sau đó sử dụng trình thiết kế bảng SSMS để đặt thuộc tính IDENTITY. Điều này cho phép bạn tạo một tập lệnh sẽ thực hiện việc thả / thêm / giữ số / đổi lại cột cho bạn.


5
OP có trên SQL Server 2008 vì vậy có một cách
Martin Smith

Toàn bộ trường hợp cần phải được bắt đầu trong chế độ người dùng duy nhất để có thể không khả thi trong hầu hết các trường hợp nhưng ALTER TABLE ... SWITCHcó thể làm điều đó mà không cần điều đó.
Martin Smith

11

Tôi đã có vấn đề này, nhưng không thể sử dụng một cột danh tính (vì nhiều lý do). Tôi giải quyết về điều này:

DECLARE @id INT
SET @id = 0 
UPDATE table SET @id = id = @id + 1 

Mượn từ đây .


4

Nếu cột đã tồn tại trong bảng của bạn và nó là null, bạn có thể cập nhật cột bằng lệnh này (thay thế id, tablename và keykey):

UPDATE x
SET x.<Id> = x.New_Id
FROM (
  SELECT <Id>, ROW_NUMBER() OVER (ORDER BY <tablekey>) AS New_Id
  FROM <tablename>
  ) x

Bạn đã tiết kiệm thời gian cho tôi với cái này! Phụ lục tốt cho câu trả lời của @ gbn.
Kristen Waite

2

Khi chúng ta thêm và nhận dạng cột trong một bảng hiện có, nó sẽ tự động điền vào mà không cần phải điền nó theo cách thủ công.


2

bởi nhà thiết kế, bạn có thể đặt danh tính (1,1) nhấp chuột phải vào tbl => desing => ở phần bên trái (nhấp chuột phải) => thuộc tính => trong cột nhận dạng, chọn #column

Tính chất

cột idendtity


1
Bạn có thông tin về việc đây có phải là một cách tiếp cận tốt không? OP đang hỏi liệu đó có phải là "cách tiến hành chính xác" hay không. Một câu trả lời đầy đủ hơn có thể giúp họ biết những ưu / nhược điểm của phương pháp này.
jinglểula

Thực sự tôi đang sử dụng tùy chọn này trong môi trường phát triển, nếu bạn không chuyển sự thay đổi này sang sản xuất, bạn nên thông báo với VIEW DEPENDENCY nếu trường nhận dạng đang được sử dụng bởi một số thủ tục Store o kích hoạt.
gustavo herrera

2

Nếu bảng của bạn có mối quan hệ với các bảng khác bằng khóa chính hoặc khóa trước, có thể không thể thay đổi bảng của bạn. Vì vậy, bạn cần phải thả và tạo bảng một lần nữa.
Để giải quyết những vấn đề này, bạn cần phải tạo Tập lệnh bằng cách nhấp chuột phải vào cơ sở dữ liệu và trong tùy chọn nâng cao, đặt loại dữ liệu thành tập lệnh để lập sơ đồ và dữ liệu. sau đó, sử dụng tập lệnh này với việc thay đổi cột của bạn để xác định và tạo lại bảng bằng cách chạy truy vấn của nó.
truy vấn của bạn sẽ giống như ở đây:

USE [Db_YourDbName]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Drop TABLE [dbo].[Tbl_TourTable]

CREATE TABLE [dbo].[Tbl_TourTable](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NULL,
    [Family] [nvarchar](150) NULL)  

GO

SET IDENTITY_INSERT [dbo].[Tbl_TourTable] ON 

INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')

SET IDENTITY_INSERT [dbo].[Tbl_TourTable] off 

0

Đây là một ý tưởng bạn có thể thử. Bảng gốc - không có cột nhận dạng bảng1 tạo bảng mới - gọi bảng2 cùng với cột định danh. sao chép dữ liệu từ bảng1 sang bảng2 - cột nhận dạng được điền tự động với các số tăng tự động.

đổi tên bảng gốc - bảng1 thành bảng3 đổi tên bảng mới - bảng2 thành bảng1 (bảng gốc) Bây giờ bạn có bảng1 với cột nhận dạng được bao gồm và được điền cho dữ liệu hiện có. sau khi chắc chắn rằng không có vấn đề gì và hoạt động bình thường, hãy bỏ bảng3 khi không còn cần thiết.


0

Tạo một Bảng mới với tên khác nhau và các cột giống nhau, liên kết Khóa chính và Khóa ngoài và liên kết bảng này trong câu lệnh chèn mã của bạn. Ví dụ: Đối với NHÂN VIÊN, thay thế bằng NHÂN VIÊN.

CREATE TABLE EMPLOYEES(

    EmpId        INT NOT NULL IDENTITY(1,1), 
    F_Name       VARCHAR(20) ,
    L_Name       VARCHAR(20) ,
    DOB          DATE ,
    DOJ          DATE ,
    PRIMARY KEY (EmpId),
    DeptId int FOREIGN KEY REFERENCES DEPARTMENT(DeptId),
    DesgId int FOREIGN KEY REFERENCES DESIGNATION(DesgId),
    AddId int FOREIGN KEY REFERENCES ADDRESS(AddId)   
) 

Tuy nhiên, bạn phải xóa Bảng NHÂN VIÊN hiện có hoặc thực hiện một số điều chỉnh theo yêu cầu của bạn.


0

Câu trả lời này là một bổ sung nhỏ cho câu trả lời được bình chọn cao nhất và hoạt động cho SQL Server. Câu hỏi yêu cầu khóa chính tăng tự động, câu trả lời hiện tại không thêm khóa chính, nhưng nó không được gắn cờ là tăng tự động. Kịch bản bên dưới kiểm tra các cột, sự tồn tại và thêm nó với cờ tự động được bật.

IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTable' AND COLUMN_NAME = 'PKColumnName')
BEGIN


ALTER TABLE dbo.YourTable
   ADD PKColumnName INT IDENTITY(1,1)

CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED

END

GO

0
ALTER TABLE table_name ADD temp_col INT IDENTITY(1,1) 
update 

5
Bạn có thể giải thích nó được không?
Muhammad Dyas Yaskur

1
Mặc dù mã này có thể giải quyết vấn đề của OP, tốt nhất là bao gồm một lời giải thích về cách mã của bạn giải quyết vấn đề của OP. Theo cách này, khách truy cập trong tương lai có thể học hỏi từ bài đăng của bạn và áp dụng nó vào mã của riêng họ. SO không phải là một dịch vụ mã hóa, mà là một nguồn tài nguyên cho kiến ​​thức. Ngoài ra, chất lượng cao, câu trả lời đầy đủ có nhiều khả năng được nâng cao. Các tính năng này, cùng với yêu cầu tất cả các bài đăng đều khép kín, là một số điểm mạnh của SO như một nền tảng, khác biệt với các diễn đàn. Bạn có thể chỉnh sửa để thêm thông tin bổ sung & / hoặc để bổ sung giải thích của bạn với tài liệu nguồn.
ysf

-1

thay đổi bảng / ** dán tên của bảng ** / thêm id int IDENTITY (1,1)

xóa khỏi / ** dán tên của bảng ** / trong đó id trong

(

chọn a.id TỪ / ** dán tên của tabal / như một LEFT OUTER JOIN (SELECT MIN (id) như id TỪ / dán tên của tabal / GROUP BY / dán cột c1, c2 .... ** /

) as t1 
ON a.id = t1.id

Ở đâu t1.id LÀ NULL

)

thay đổi bảng / ** dán tên của bảng ** / id DROP COLUMN


Câu hỏi của bạn là gì? Cách hỏi
Ann Kilzer

1
Chỉnh sửa câu trả lời của bạn, sử dụng markdown để định dạng đúng ví dụ mã của bạn.
Bill Keller

-3

Hãy thử một cái gì đó như thế này (trên bàn thử nghiệm trước):

SỬ DỤNG your_database_name
ĐI
WHILE (CHỌN COUNT (*) TỪ your_table WHERE your_id_field IS NULL)> 0
BẮT ĐẦU
    THIẾT LẬP ROWCOUNT 1
    CẬP NHẬT your_table SET your_id_field = MAX (your_id_field) +1
KẾT THÚC
IN 'TẤT CẢ ĐÔI'

Tôi chưa thử nghiệm điều này chút nào, vì vậy hãy cẩn thận!


1
-1 Không trả lời câu hỏi (đó là về việc thêm IDENTITYcột) và dù sao cũng không hoạt động. UPDATE your_table SET your_id_field = MAX(your_id_field)+1bạn không thể tặc lưỡi ở MAXđó. Đâu là một WHEREmệnh đề để tránh chỉ cập nhật liên tục cùng một hàng?
Martin Smith

-3

Điều này hoạt động trong MariaDB, vì vậy tôi chỉ có thể hy vọng nó hoạt động trong SQL Server: bỏ cột ID bạn vừa chèn, sau đó sử dụng cú pháp sau: -

THAY ĐỔI BẢNG tên_bảng THÊM id id INT PRIMARY KEY AUTO_INCREMENT;

Không cần bàn khác. Điều này chỉ đơn giản là chèn một cột id, làm cho nó trở thành chỉ mục chính và điền vào nó các giá trị tuần tự. Nếu SQL Server không làm điều này, tôi xin lỗi vì đã lãng phí thời gian của bạn.


-3

THAY ĐỔI BẢNG tên_bảng THÊM ID COLUMN INT KHÔNG NULL PRIMary KEY AUTO_INCREMENT; Điều này có thể hữu ích

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.