Làm cách nào để tăng tất cả các EmployeeIDgiá trị của tôi lên một nếu nó là khóa chính?
Làm cách nào để tăng tất cả các EmployeeIDgiá trị của tôi lên một nếu nó là khóa chính?
Câu trả lời:
Tôi giả định rằng câu hỏi này là về cách cập nhật một loạt các hàng thành giá trị cao hơn mà không phải dẫm đạp lên nhau. Nếu bạn cập nhật id = 1 thành id = 2 ở hàng đầu tiên trong khi hàng thứ hai (với id = 2) vẫn ở đó, bạn sẽ bị vi phạm khóa chính vì bây giờ bạn có hai hàng với id = 2.
Để ngăn chặn loại va chạm đó, bạn chỉ cần bắt đầu ở giá trị lớn nhất và tăng thêm một. điều đó mở ra một khoảng trống cho giá trị lớn thứ hai để di chuyển vào đó lần lượt mở ra một khoảng trống cho giá trị lớn thứ ba để di chuyển vào, v.v.
Tuy nhiên, trong SQL Server, bạn không cần phải lo lắng, vì công cụ sẽ tự động xử lý việc đó:
Thiết lập lược đồ MS SQL Server 2008 :
CREATE TABLE dbo.Employee(Id INT PRIMARY KEY CLUSTERED, Name NVARCHAR(MAX));
INSERT INTO dbo.Employee(Id,Name)
VALUES(1,'John'),(2,'Jane'),(3,'Max');
Truy vấn 1 :
SELECT * FROM dbo.Employee;
Kết quả :
| ID | NAME |
|----|------|
| 1 | John |
| 2 | Jane |
| 3 | Max |
Truy vấn 2 :
UPDATE dbo.Employee
SET Id = Id + 1;
Truy vấn 3 :
SELECT * FROM dbo.Employee;
Kết quả :
| ID | NAME |
|----|------|
| 2 | John |
| 3 | Jane |
| 4 | Max |
Truy vấn 4 :
UPDATE dbo.Employee
SET Id = Id - 1;
Truy vấn 5 :
SELECT * FROM dbo.Employee;
Kết quả :
| ID | NAME |
|----|------|
| 1 | John |
| 2 | Jane |
| 3 | Max |
Nếu bạn thực sự theo liên kết SQL Fiddle , bạn cũng có thể thấy các kế hoạch thực hiện cho hai câu lệnh cập nhật. Cái đầu tiên trông như thế này:

Ở đó bạn có thể thấy khá xa bên trái một Table Spooltoán tử. Toán tử đó về cơ bản tạo ra một bản sao của tất cả các hàng đã được cập nhật trước khi chúng được ghi lại bởi toán tử `Clustered Index Update 'bên cạnh nó. Do SQL Server này có thể xử lý các cập nhật "chồng chéo" mà không bị vấp ngã.
Một lợi ích bổ sung (và lý do ban đầu tại sao hành vi này được thực hiện) là cách tiếp cận hai bước này cung cấp Bảo vệ Halloween .
Không có nhiều chi tiết hơn về cấu trúc cơ sở dữ liệu của bạn, có một số lượng lớn các biến ở đây.
Nếu bất kỳ bảng nào khác chứa ID nhân viên làm tham chiếu cho bảng này và các khóa giả mạo được thiết lập đúng và được đặt thành ON UPDATE CASCADEthì việc thực thi đơn giản UPDATE EmployeeTable SET EmployeeID = EmployeeID + 1sẽ thực hiện thủ thuật - các mối quan hệ FK sẽ cập nhật mọi thứ khác khi cần. Nếu không có ON UPDATE CASCADEtrong trường hợp này, bạn sẽ nhận được lỗi và tuyên bố sẽ thất bại.
Nếu bạn có các bảng tham chiếu đến ID nhân viên mà không có các ràng buộc khóa giả mạo thì bạn cũng sẽ phải cập nhật các bảng đó UPDATE AnotherTable SET EmployeeID = EmployeeID + 1. Bạn nên bọc tất cả các cập nhật bảng trong một giao dịch (có xử lý lỗi để đảm bảo giao dịch được khôi phục hoặc SET XACT_ABORT ONnếu bạn không cần bất kỳ kiểm soát nào tốt hơn đối với quy trình đó) để duy trì tính nhất quán (vì vậy nếu có lỗi xảy ra trở lại).
Tôi sẽ hỏi tại sao bạn muốn làm điều này mặc dù. Mã định danh nhân viên nói chung là một khóa thay thế (còn được gọi là khóa giả) không có ý nghĩa gì ngoài việc xác định một người nhất định (nó có thể là một chữ cái UUID của một số, ngoại trừ thực tế nó được sử dụng trong văn bản trong thế giới thực xuống, vì vậy một UUID sẽ không thuận tiện). Xem chương "psuedo-key Simpl-freak" trong SQL Antipotypes để biết thêm thảo luận về vấn đề này.