Ve vašem původním přístupu byly dvě špatné věci.
- Při vkládání do tabulky nebylo nikdy zaručeno, že
ORDER BY
naINSERT ... SELECT ... ORDER BY
by bylo pořadí, ve kterém byly řádky skutečně vloženy. - Při výběru z něj SQL Server nezaručuje, že
SELECT
bezORDER BY
vrátí řádky v libovolném konkrétním pořadí, jako je například objednávka vložení.
V roce 2012 to vypadá, jako by se chování změnilo s ohledem na položku 1. Nyní obecně ignoruje ORDER BY
na SELECT
příkaz, který je zdrojem pro INSERT
DECLARE @T TABLE(number int)
INSERT INTO @T
SELECT number
FROM master..spt_values
ORDER BY name
Plán 2008
Plán 2012
Důvodem změny chování je to, že v předchozích verzích SQL Server vytvářel jeden plán, který byl sdílen mezi spuštěními pomocí SET ROWCOUNT 0
(vypnuto) a SET ROWCOUNT N
. Operátor řazení tu byl pouze proto, aby zajistil správnou sémantiku v případě, že plán spouštěla relace s nenulovým ROWCOUNT
soubor. TOP
operátor nalevo od něj je ROWCOUNT TOP
.
SQL Server 2012 nyní vytváří samostatné plány pro tyto dva případy, takže je není potřeba přidávat do ROWCOUNT 0
verzi plánu.
Řazení se může v plánu objevit i v roce 2012, pokud SELECT
má explicitní TOP
definováno (jiné než TOP 100 PERCENT
), ale stále to nezaručuje skutečné pořadí vložení řádků, plán pak může mít jiné řazení za TOP N
je vytvořen, aby například dostal řádky do seskupeného indexového pořadí.
Pro příklad ve vaší otázce bych jen upravil volací kód tak, aby specifikoval ORDER BY name
pokud to vyžaduje.
Ohledně vašeho sort_id
nápad z Záruky objednávek v SQL Server
je zaručena při vkládání do tabulky s IDENTITY
že pořadí, které jsou tyto přiděleny, bude podle ORDER BY
takže můžete také udělat
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
ale stále byste museli objednávat podle sort_id
ve vašem výběru dotazů, protože bez toho není zaručena objednávka (možná toto sort_id
přístup může být užitečný v případě, kdy se původní sloupce použité pro řazení nekopírují do proměnné tabulky)