Det var två saker fel med ditt ursprungliga tillvägagångssätt.
- När du infogade i tabellen var det aldrig garanterat att
ORDER BYpåINSERT ... SELECT ... ORDER BYskulle vara den ordning som raderna faktiskt infogades. - När du väljer från den garanterar inte SQL Server att
SELECTutan enORDER BYkommer att returnera raderna i vilken ordning som helst, såsom insättningsordning ändå.
Under 2012 ser det ut som om beteendet har ändrats med avseende på punkt 1. Den ignorerar nu generellt ORDER BY på SELECT sats som är källan till en INSERT
DECLARE @T TABLE(number int)
INSERT INTO @T
SELECT number
FROM master..spt_values
ORDER BY name
2008-plan

2012-plan

Anledningen till beteendeförändringen är att SQL Server i tidigare versioner producerade en plan som delades mellan körningar med SET ROWCOUNT 0 (av) och SET ROWCOUNT N . Sorteringsoperatorn var bara där för att säkerställa korrekt semantik om planen kördes av en session med en ROWCOUNT som inte är noll uppsättning. TOPP operatorn till vänster om den är en ROWCOUNT TOP
.
SQL Server 2012 producerar nu separata planer för de två fallen så det finns inget behov av att lägga till dessa i ROWCOUNT 0 version av planen.
En sortering kan fortfarande visas i planen under 2012 om SELECT har en explicit TOPP definierade (annat än TOPP 100 PROCENT ) men detta garanterar fortfarande inte faktisk insättningsordning för rader, planen kan då ha en annan sortering efter TOP N är etablerad för att till exempel få raderna i klustrad indexordning.
För exemplet i din fråga skulle jag bara justera anropskoden för att specificera ORDER BY name om det är vad det kräver.
Angående ditt sort_id idé från Beställningsgarantier i SQL Server
det garanteras när du infogar i en tabell med IDENTITY att ordningen dessa tilldelas kommer att vara enligt ORDER BY så kan du också göra
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
men du skulle fortfarande behöva beställa med sort_id i dina valfrågor eftersom det inte finns någon garanterad beställning utan det (kanske detta sort_id tillvägagångssätt kan vara användbart i de fall där originalkolumnerna som används för beställning inte kopieras till tabellvariabeln)