SÉLECTIONNEZ * EN conserve COMMANDE PAR dans SQL Server 2008, mais pas en 2012
Exécuter la requête SQL suivante en 2008 et en 2012. Lorsqu'il est exécuté en 2008, le résultat retourné est dans le bon ordre de tri. En 2012, l'ordre de tri n'est pas conservé.
Est-ce un connu de changement? Est-il un travail autour de pour 2012 afin de conserver l'ordre de tri?
CREATE TABLE #MyTable(Name VARCHAR(50), SortOrder INT)
INSERT INTO #MyTable SELECT 'b', 2 UNION ALL SELECT 'c', 3 UNION ALL SELECT 'a', 1 UNION ALL SELECT 'e', 5 UNION ALL SELECT 'd', 4
SELECT * INTO #Result FROM #MyTable ORDER BY SortOrder
SELECT * FROM #Result
DROP TABLE #MyTable
DROP TABLE #Result
Une table dans SQL Server n'a jamais d'ordre implicite - si vous avez besoin d'un ordre spécifique, vous offre une
ORDER BY
clause à votre SELECT
déclaration pour l'obtenir.OriginalL'auteur Rivka | 2013-05-20
Vous devez vous connecter pour publier un commentaire.
Comment pouvez-vous dire ce que l'ordre est à l'intérieur d'un tableau en utilisant
select * from #result
? Il n'existe aucune garantie quant à l'ordre dans unselect
requête.Cependant, les résultats sont différents sur SQL Violon. Si vous voulez vous assurer que les résultats sont les mêmes, puis ajouter une clé primaire. Ensuite, l'ordre d'insertion est garanti:
J'ai toujours horreur de faire
select * from Result
après ce. Mais oui, il le fait revenir dans le bon ordre dans SQL Server 2008 et 2012. Non seulement cela, mais parce que SQL Server garantit que les clés primaires sont insérées dans le bon ordre, les enregistrements sont même garantis dans l'ordre correct dans ce cas.MAIS . . . tout simplement parce que les dossiers sont dans un ordre particulier sur les pages ne signifie pas qu'ils seront récupérés dans l'ordre sans
order by
clause.OriginalL'auteur Gordon Linoff
Lors de l'utilisation de
ORDER BY
avec unINSERT
, il n'a jamais été garanti pour faire autre chose que de contrôler l'ordre de la colonne d'identité si présent.Antérieures à SQL Server 2012, l'optimiseur a toujours produit un plan comme si une colonne d'identité existe, et semble donc correct. SQL Server 2012 correctement, de ne pas assumer une colonne d'identité existe, et seules les commandes si le tableau a réellement une colonne d'identité.
De sorte que vous pouvez résoudre ce problème en ajoutant une colonne d'Identité à votre temp résultat de la table.
Cependant, vous devriez vraiment juste ajouter un
ORDER BY
clause à votreSELECT
déclaration?SELECT
déclarations sansORDER BY
n'ont jamais été garanti pour retourner les résultats dans un ordre particulier. Toujours ajouter leORDER BY
clause pour vous assurer de recevoir les résultats de la façon dont vous vous attendez.La raison de la différence de comportement n'est pas parce que SQL Server toujours cru qu'il y avait une
IDENTITY
colonne. C'est parce que dans les versions antérieures à 2012 les plans produits nécessaires pour être apte à savoir si ou de ne pas courir avec un zéroSET ROWCOUNT
option. 2012 met en cache les plans avec non nul, le nombre de lignes séparément, donc il est inutile de polluer le plan principal avec ces opérateurs.OriginalL'auteur sgeddes
Tout d'abord, merci sgeddes pour l'explication, il m'a beaucoup aidé.
La chose à propos de la définition d'une variable de table ou de la création d'une table temporaire est que vous devez le définir, et si vous allez à aller à travers le travail de définition, vous pourriez aussi bien faire l'insert de la bonne façon:
Dans mon cas, la COMMANDE PAR l'INSERTION a été dynamique, donc quand j'ai appelé "SELECT * from #Résultat", l'ORDRE était inconnu. Ma solution a été d'ajouter la fonction ROW_NUMBER colonne que j'ai pu coder en dur dans le SÉLECTIONNER quand j'ai été les données.
Oui, j'ai encore à inclure une clause ORDER BY, mais au moins il est statique. Voici ce que j'ai fait:
Espère que cette aide.
OriginalL'auteur Losbear
Si vous avez différents triés résultats lors de l'interrogation de chaque base de données, le classement est probablement différente entre les deux.
Essayer explicitement paramètre le classement dans votre requête et voir si vos résultats sont retournés dans le même ordre dans les deux bases de données, par exemple
OriginalL'auteur George Johnston
Solution de contournement :
Vous pouvez ajouter un
SET ROWCOUNT
avant ce type de requête, puis mis à zéro après le réinitialiser, il fonctionne. Cela va forcer SQL pour maintenir l'ordre dans votre requête.OriginalL'auteur patrick imbault
Vous devez créer la fonction ROW_NUMBER() de la colonne que vous souhaitez commander. Commande par directement dans la sélection, est ignoré lors de l'insertion est exécutée.
OriginalL'auteur Snowww