Tăng tất cả các giá trị khóa chính lên 1


7

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?


5
@RolandoMySQLDBA tại sao bài tập về nhà lại lạc đề chỉ vì đó là bài tập về nhà? Bạn có thể đưa ra câu trả lời cho những người không thể tự làm việc của mình không, nhưng không thể đưa ra câu trả lời cho những người không thể tự làm bài tập về nhà? Tôi nghĩ rằng chúng ta có thể hợp lý hơn thế nhiều .
Aaron Bertrand

Câu trả lời:


10

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 đó:

Câu đố SQL

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;

Kế hoạch thực hiện

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;

Kế hoạch thực hiện

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:

nhập mô tả hình ảnh ở đâ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 .


2
Bộ đệm bảng là cần thiết vì cột tên là loại LOB. Với tên không phải LOB, loại này cung cấp đủ tách pha cho HP. Tách-Sắp xếp-Thu gọn tối ưu hóa ghi nhật ký và đảm bảo các thay đổi được áp dụng theo thứ tự ngăn chặn vi phạm khóa tạm thời.
Paul White 9

@PaulWhite, cảm ơn bạn đã bình luận rõ ràng. Bạn đang đưa ra khá nhiều khái niệm trong câu ngắn của bạn ở trên. Có một trong các bài viết của bạn đi vào chi tiết hơn?
Sebastian Meine

2
Tôi đã phải kiểm tra, nhưng có! Tôi thảo luận về Chia-Sắp xếp-Thu gọn trong bài này và Bảo vệ Halloween trong một loạt bốn phần . Conor Cickyham nói về việc tối ưu hóa đăng nhập trong chương của cuốn sách SQL Server 2008 Internals của MS Press.
Paul White 9

4

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.

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.