Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Déterminer la dernière ligne ajoutée lorsqu'aucun index n'est présent

Non, il n'y a pas de fonction prédéfinie dans SQL Server qui renverra la "dernière ligne" d'une table.

Par définition, une table est un ensemble non ordonné de lignes. Imaginez que vous jetez un tas de billes dans un sac. Maintenant, ouvrez le sac et demandez à quelqu'un d'autre quelle bille est entrée en premier ou en dernier. Maintenant, jetez-les tous sur le sol, et quand quelqu'un d'autre entre dans la pièce, demandez-lui lequel a touché le sol en premier ou en dernier. Vous ne pouvez pas le faire, car il n'y a aucune information supplémentaire qui indique quoi que ce soit sur l'ordre dans lequel ils sont tombés.

Il en va de même pour une table dans SQL Server. À moins que vous n'ajoutiez une colonne IDENTITY, une colonne datetime ou un déclencheur, ou que vous n'utilisiez des fonctionnalités externes telles que le suivi des modifications, le CDC, l'audit, etc., SQL Server n'a aucun moyen de vous dire quelle ligne a été insérée en dernier. Vous pouvez penser qu'il suffit de sélectionner dans le tableau sans clause order by regarde comme s'il renvoyait des données dans le bon ordre, c'est une pure coïncidence. Voici un exemple :

CREATE TABLE dbo.floobat
(
  ID INT PRIMARY KEY, 
  n VARCHAR(16), 
  x CHAR(4000) NOT NULL DEFAULT ''
);

INSERT dbo.floobat(ID,n) VALUES(1,'Sparky');
INSERT dbo.floobat(ID,n) VALUES(2,'Aaron');
INSERT dbo.floobat(ID,n) VALUES(3,'Norbert'); -- <-- inserted last

SELECT ID, n FROM dbo.floobat;

Ok, donc par défaut, cela semble être correct. Résultats :

ID    n
--    -------
1     Sparky
2     Aaron
3     Norbert -- < yes, this is right

Cependant, apportons une modification au tableau dont votre application ou tout ce qui dépend de l'ordre ci-dessus n'aura aucune idée :

CREATE NONCLUSTERED INDEX x ON dbo.floobat(n);

SELECT ID, n FROM dbo.floobat;

Oh oh ! Résultats :

ID    n
--    -------
2     Aaron
3     Norbert
1     Sparky -- < oops, this is no longer right

Vous devez vous rappeler ceci :si vous n'incluez pas de clause ORDER BY, vous indiquez SQL Server que vous ne vous souciez pas de commander. Il va donc trouver le moyen le plus efficace de renvoyer les données, ce qui pourrait conduire à un ordre différent observé. L'ajout de l'index ci-dessus a donné à SQL Server un meilleur chemin d'accès pour récupérer les données. Il utilisait toujours une analyse, mais cet index était beaucoup plus fin que l'index clusterisé (qui ne pouvait contenir que deux lignes sur une page).

Même sans l'index, vous n'obtiendriez probablement pas les résultats escomptés, car il est compliqué par le fait que votre Cust_ID la colonne n'est pas insérée dans l'ordre croissant. Donc, si vous insérez 5 et que 2 , la sélection sans ORDER BY entraînera en fait 2 puis 5 (en supposant qu'aucun meilleur indice n'existe).

D'autres choses que la création (ou la suppression, la modification ou la reconstruction) d'un index peuvent entraîner le même type de changement dans le comportement de classement. Appliquez un service pack, une CU ou un correctif ; vider le cache de procédure ; en utilisant diverses options RECOMPILE ; mise à jour des statistiques ; redémarrer le serveur ; ajouter ou désactiver un indicateur de trace ; modifier les options d'une option de serveur ; déplacer la base de données vers un autre serveur ; etc. etc.

Donc, si vous souhaitez suivre ces informations, vous devrez les ajouter vous-même d'une manière ou d'une autre, comme plusieurs des autres réponses l'ont abordé.