Havia duas coisas erradas com sua abordagem original.
- Ao inserir na tabela, nunca foi garantido que o
ORDER BYnoINSERT ... SELECT ... ORDER BYseria a ordem em que as linhas foram realmente inseridas. - Ao selecionar a partir dele, o SQL Server não garante que
SELECTsem umORDER BYretornará as linhas em qualquer ordem específica, como ordem de inserção.
Em 2012, parece que o comportamento mudou em relação ao item 1. Agora geralmente ignora o
ORDER BY no SELECT declaração que é a fonte para um INSERT DECLARE @T TABLE(number int)
INSERT INTO @T
SELECT number
FROM master..spt_values
ORDER BY name
Plano 2008
Plano 2012
O motivo da mudança de comportamento é que nas versões anteriores o SQL Server produzia um plano que era compartilhado entre as execuções com
SET ROWCOUNT 0 (desligado) e SET ROWCOUNT N . O operador de classificação estava lá apenas para garantir a semântica correta caso o plano fosse executado por uma sessão com um ROWCOUNT diferente de zero definir. O TOP operador à esquerda dele é um ROWCOUNT TOP
. O SQL Server 2012 agora produz planos separados para os dois casos, portanto, não há necessidade de adicioná-los ao
ROWCOUNT 0 versão do plano. Uma classificação ainda pode aparecer no plano em 2012 se o
SELECT tem um TOP explícito definido (diferente de TOP 100 PERCENT ), mas isso ainda não garante a ordem de inserção real das linhas, o plano pode ter outra classificação após o TOP N é estabelecido para obter as linhas em ordem de índice clusterizado, por exemplo. Para o exemplo em sua pergunta, eu apenas ajustaria o código de chamada para especificar
ORDER BY name se é isso que requer. Em relação ao seu
sort_id ideia de Garantias de pedidos no SQL Server
é garantido ao inserir em uma tabela com IDENTITY que a ordem em que eles são alocados será de acordo com o ORDER BY então você também pode fazer 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
mas você ainda precisaria fazer o pedido pelo
sort_id em suas consultas de seleção, pois não há pedidos garantidos sem isso (talvez este sort_id abordagem pode ser útil no caso em que as colunas originais usadas para ordenação não estão sendo copiadas para a variável da tabela)