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 BYtrênINSERT ... SELECT ... ORDER BYsẽ 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
SELECTkhông cóORDER BYvẫ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)