Som standard är ORA_ROWSCN
lagras på blocknivå, inte på radnivå. Den lagras bara på radnivå om tabellen ursprungligen byggdes med ROWDEPENDENCIES
aktiverad. Förutsatt att du kan passa många rader i din tabell i ett enda block och att du inte använder APPEND
tips om att infoga den nya datan ovanför den befintliga högvattenmärket i tabellen, infogar du sannolikt nya data i block som redan har vissa befintliga data i sig. Som standard kommer det att ändra ORA_ROWSCN
av varje rad i blocket vilket gör att din fråga räknar fler rader än vad som faktiskt infogades.
Sedan ORA_ROWSCN
är garanterat endast en övre gräns förra gången det fanns DML på en rad, skulle det vara mycket vanligare att fastställa hur många rader som infogades idag genom att lägga till en CREATE_DATE
kolumnen till tabellen som som standard är SYSDATE
eller att lita på SQL%ROWCOUNT
efter din INSERT
körde (förutsatt, naturligtvis, att du använder en enda INSERT
för att infoga alla rader).
I allmänhet använder du ORA_ROWSCN
och SCN_TO_TIMESTAMP
funktion kommer att vara ett problematiskt sätt att identifiera när en rad infogades även om tabellen är byggd med ROWDEPENDENCIES
. ORA_ROWSCN
returnerar ett Oracle SCN som är ett systemändringsnummer. Detta är en unik identifierare för en viss ändring (dvs en transaktion). Som sådan finns det ingen direkt koppling mellan ett SCN och en tid - min databas kan generera SCN:er en miljon gånger snabbare än din och min SCN 1 kan skilja sig från din SCN 1 i flera år. Oracle-bakgrundsprocessen SMON
upprätthåller en tabell som mappar SCN-värden till ungefärliga tidsstämplar, men den upprätthåller bara dessa data under en begränsad tidsperiod - annars skulle din databas sluta med en tabell med flera miljarder rader som bara lagrade SCN till tidsstämpelmappningar. Om raden infogades för mer än till exempel en vecka sedan (och den exakta gränsen beror på databasen och databasversionen), SCN_TO_TIMESTAMP
kommer inte att kunna konvertera SCN till en tidsstämpel och kommer att returnera ett fel.