sql >> Database teknologi >  >> RDS >> Sqlserver

Bestem den seneste tilføjede række, når der ikke er noget indeks til stede

Nej, der er ingen foruddefineret funktion i SQL Server, som returnerer den "sidste række" i en tabel.

Per definition er en tabel et uordnet sæt rækker. Forestil dig, at du smider en masse kugler i en pose. Åbn nu posen og spørg en anden, hvilken marmor der gik i først eller sidst. Smid nu dem alle sammen på gulvet, og når en anden kommer ind i rummet, så spørg dem, hvem der rammer gulvet først eller sidst. Det kan du ikke, for der er ingen yderligere oplysninger, der indikerer noget om, hvilken rækkefølge de faldt i.

Det samme gælder for en tabel i SQL Server. Medmindre du tilføjer en IDENTITY-kolonne eller en datetime-kolonne eller en trigger eller bruger ekstern funktionalitet som ændringssporing, CDC, revision osv., er der ingen måde for SQL Server at fortælle dig, hvilken række der sidst blev indsat. Du kan tænke at bare at vælge fra tabellen uden en ordre efter klausul looks Ligesom det returnerer data i den rigtige rækkefølge, er dette ren tilfældighed. Her er et eksempel:

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, så som standard ser dette ud til at være okay. Resultater:

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

Lad os dog foretage en ændring af tabellen, som din ansøgning eller hvad der ellers er baseret på ovenstående bestilling ikke har nogen idé om:

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

SELECT ID, n FROM dbo.floobat;

Åh åh! Resultater:

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

Du skal huske dette:Hvis du ikke inkluderer en ORDER BY-klausul, er du fortæller SQL Server, som du er ligeglad med at bestille. Så det vil finde den mest effektive måde at returnere dataene på, og det kan føre til en anden observeret rækkefølge. Tilføjelse af indekset ovenfor gav SQL Server en bedre adgangssti til at hente dataene. Det brugte stadig en scanning, men det indeks var meget tyndere end det klyngede indeks (som kun kunne passe til to rækker på en side).

Selv uden indekset ville du sandsynligvis ikke få de resultater, du forventer, da det er indviklet af det faktum, at dit Cust_ID kolonne indsættes ikke i stigende rækkefølge. Så hvis du indsætter 5 og end 2 , vil valg uden ORDER BY faktisk resultere i 2 derefter 5 (forudsat at der ikke findes et bedre indeks).

Andre ting end at oprette (eller droppe, eller ændre eller genopbygge) et indeks kan forårsage den samme slags ændring i ordreadfærd. Anvend en service pack, CU eller hotfix; skylning af procedurecachen; ved hjælp af forskellige RECOMPILE-muligheder; opdatering af statistik; genstart af serveren; tilføje eller deaktivere et sporingsflag; ændring af en server indstillingsmuligheder; flytning af databasen til en anden server; osv. osv.

Så hvis du vil spore disse oplysninger, skal du selv tilføje dem på en eller anden måde, som flere af de andre svar har adresseret.



  1. Databasedesign:Flere tabeller vs en enkelt tabel

  2. Matlab og MySQL fandt ingen passende driver

  3. Brug værdien af ​​en strengvariabel i SQL FOR-IN (SELECT) loop

  4. Entity Framework kerne - Indeholder er der forskel på store og små bogstaver eller ufølsom?