Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Chức năng Table-Valued - Thứ tự theo bị bỏ qua trong đầu ra

Có hai điều sai với cách tiếp cận ban đầu của bạn.

  1. Khi chèn vào bảng, không bao giờ được đảm bảo rằng ORDER BY trên INSERT ... SELECT ... ORDER BY sẽ là thứ tự mà các hàng đã thực sự được chèn.
  2. 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 SELECTTOP 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)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Văn bản bị cắt ngắn hoặc một hoặc nhiều ký tự không khớp trong trang mã đích Khi nhập từ tệp Excel

  2. Truy vấn SQL phân biệt giữa ß và ss

  3. Trả về giá trị từ câu lệnh INSERT trong SQL Server 2008

  4. C ++ xác định trước độ dài của VARCHAR bằng cách sử dụng các tham số liên kết ODBC

  5. Tham gia tự nhiên trong SQL Server