Có hai điều sai với cách tiếp cận ban đầu của bạn.
- Khi chèn vào bảng, không bao giờ được đảm bảo rằng
ORDER BY
trênINSERT ... SELECT ... ORDER BY
sẽ là thứ tự mà các hàng đã thực sự được chèn. - Khi chọn từ nó SQL Server không đảm bảo rằng
SELECT
không cóORDER BY
vẫn sẽ trả về các hàng theo bất kỳ thứ tự cụ thể nào, chẳng hạn như thứ tự chèn.
Vào năm 2012, có vẻ như hành vi đã thay đổi đối với mục 1. Bây giờ nó thường bỏ qua ORDER BY
trên SELECT
câu lệnh là nguồn cho một INSERT
DECLARE @T TABLE(number int)
INSERT INTO @T
SELECT number
FROM master..spt_values
ORDER BY name
Kế hoạch 2008
Kế hoạch 2012
Lý do cho sự thay đổi hành vi là trong các phiên bản trước SQL Server đã tạo ra một kế hoạch được chia sẻ giữa các lần thực thi với SET ROWCOUNT 0
(tắt) và SET ROWCOUNT N
. Toán tử sắp xếp chỉ ở đó để đảm bảo ngữ nghĩa chính xác trong trường hợp kế hoạch được chạy bởi một phiên có ROWCOUNT
khác 0 bộ. TOP
ở bên trái của nó là một ROWCOUNT TOP
.
SQL Server 2012 hiện tạo các kế hoạch riêng biệt cho hai trường hợp vì vậy không cần thêm các kế hoạch này vào ROWCOUNT 0
phiên bản của kế hoạch.
Một loại có thể vẫn xuất hiện trong kế hoạch vào năm 2012 nếu SELECT
có TOP
rõ ràng được xác định (ngoài TOP 100 PERCENT
) nhưng điều này vẫn không đảm bảo thứ tự chèn thực tế của các hàng, kế hoạch sau đó có thể có một sắp xếp khác sau TOP N
được thiết lập để đưa các hàng vào thứ tự chỉ mục nhóm chẳng hạn.
Đối với ví dụ trong câu hỏi của bạn, tôi sẽ chỉ điều chỉnh mã gọi điện để chỉ định ORDER BY name
nếu đó là những gì nó yêu cầu.
Về sort_id
của bạn ý tưởng từ Đảm bảo đặt hàng trong SQL Server
nó được đảm bảo khi chèn vào bảng với IDENTITY
rằng thứ tự những thứ này được phân bổ sẽ theo ORDER BY
vì vậy bạn cũng có thể làm
DECLARE @Customer TABLE (
Sort_Id INT IDENTITY PRIMARY KEY,
Customer_ID INT,
Name INT,
Expired BIT )
INSERT INTO @Customer
SELECT Customer_ID,
Name,
CASE
WHEN Expiry_Date < Getdate() THEN 1
WHEN Expired = 1 THEN 1
ELSE 0
END
FROM Customer
ORDER BY Name
nhưng bạn vẫn cần đặt hàng theo sort_id
trong các truy vấn lựa chọn của bạn vì không có thứ tự đảm bảo nào mà không có điều đó (có lẽ sort_id
này phương pháp tiếp cận có thể hữu ích trong trường hợp các cột ban đầu được sử dụng để sắp xếp không được sao chép vào biến bảng)