Khi một câu lệnh chèn được thực thi, một hoặc nhiều hàng được chèn vào bảng, có cách nào để trích xuất hàng được chèn cuối cùng trong SQL Server không?
Khi một câu lệnh chèn được thực thi, một hoặc nhiều hàng được chèn vào bảng, có cách nào để trích xuất hàng được chèn cuối cùng trong SQL Server không?
Câu trả lời:
Theo định nghĩa, bảng là một túi hàng không có thứ tự ( xem # 3 tại đây ). Không có cách nào để hỏi SQL Server hàng nào được chèn cuối cùng trừ khi bạn thực hiện trong cùng một đợt với chèn. Ví dụ: nếu bảng của bạn có một IDENTITY
cột, bạn có thể sử dụng SCOPE_IDENTITY()
(không bao giờ sử dụng @@IDENTITY
, vì điều đó có thể không đáng tin nếu bạn có hoặc sẽ thêm các kích hoạt vào bảng nguồn):
INSERT dbo.table(column) SELECT 1;
SELECT SCOPE_IDENTITY();
Tổng quát hơn, bạn có thể sử dụng OUTPUT
mệnh đề không dựa vào một IDENTITY
cột (nhưng vẫn sẽ gây khó khăn cho việc xác định (các) hàng nào mà mệnh đề xác định nếu không có PK):
INSERT dbo.table(column) OUTPUT inserted.* SELECT 1;
Nếu bạn không nói về cùng một đợt, thì cách thực sự duy nhất để xác định hàng cuối cùng được chèn là sử dụng cột ngày / giờ trong đó dấu thời gian chèn được ghi lại. Nếu không, nó giống như bạn làm trống một túi bi trên sàn nhà, sau đó yêu cầu ai đó vào phòng và xác định cái nào rơi xuống sàn cuối cùng.
Bạn có thể bị cám dỗ hoặc thậm chí khuyên nên sử dụng IDENT_CURRENT()
chức năng, nhưng tôi giải thích ở đây tại sao điều này cũng không đáng tin cậy.
Bạn có thể thêm một cột để theo dõi điều này trong tương lai:
ALTER TABLE dbo.table ADD DateInserted DEFAULT CURRENT_TIMESTAMP;
Bây giờ bạn có thể tìm thấy (các) hàng cuối cùng được chèn bằng cách đơn giản:
;WITH x AS (SELECT *, r = RANK() OVER (ORDER BY DateInserted DESC)
FROM dbo.table)
SELECT * FROM x WHERE r = 1;
(Nếu bạn không muốn mối quan hệ, bạn có thể thêm một cột tie-phá vỡ vào ORDER BY
, hoặc bạn chỉ có thể thay đổi RANK()
để ROW_NUMBER()
nếu bạn không quan tâm mà các hàng cột bạn nhận được.)
Bạn có thể đưa ra giả định rằng hàng cuối cùng được chèn là giá trị nhận dạng cao nhất, nhưng điều này không nhất thiết phải như vậy. Danh tính có thể được định vị lại và nó cũng có thể được ghi đè bằng cách sử dụng SET IDENTITY_INSERT ON;
.