sql >> Databáze >  >> RDS >> Sqlserver

Funkce Table-Valued - Pořadí podle je ve výstupu ignorováno

Ve vašem původním přístupu byly dvě špatné věci.

  1. Při vkládání do tabulky nebylo nikdy zaručeno, že ORDER BY na INSERT ... SELECT ... ORDER BY by bylo pořadí, ve kterém byly řádky skutečně vloženy.
  2. Při výběru z něj SQL Server nezaručuje, že SELECT bez ORDER 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)



  1. Převeďte soubor BibTex na záznamy databáze pomocí Pythonu

  2. Postgres:Chyba při používání GROUP BY a ORDER (na heroku)

  3. počítání, kolikrát byl skript spuštěn

  4. Jak mohu udělat asynchronní databázi v JavaFX